Einzelnen Beitrag anzeigen

Benutzerbild von Delphi-Narr
Delphi-Narr

Registriert seit: 29. Aug 2009
Ort: Duisburg
437 Beiträge
 
Delphi 2007 Professional
 
#33

Re: Taschenrechner - String durchsuchen

  Alt 1. Mär 2010, 19:07
Das hier ist ein Parser, der keine Klammern berechnen kann, aber dennoch Punkt vor Strich beachtet.

Delphi-Quellcode:

function TForm1.Rechnen(Const Term:string):String;
Var SL: TStringList; //Das ist eine Variable für die Liste, in die der Term zerlegt wird.
    i: Integer; //Wird hier als Variable für diverse Schleifen benutzt
    S: string; //Ist in der folgenden Funktion der Term
    
  Begin

    {Falls das erste Zeichen ein Rechenzeichen wie + oder - ist, so wird eine Null eingefügt,
    um die Rechnung fortzusetzen (Beim Rechnen würde sonst ein Fehler auftreten)}

    S:=Term; //Term wird in S kopiert
    case S[1] of
    '+','-':
    begin
         insert('0',S,1);
    end;

    {Die Rechenzeichen am Anfang des Terms * und / werden gelöscht und somit ignoriert}
    
    '*','/':
    begin
         Delete(S,1,1);
    end;
    end;

    //Rechenzeichen am Ende werden gelöscht
    
    case S[Length(S)] of
    '+','-','*','/':
    begin
         Delete(S,Length(S),1);
    end;
    end;


    
    SL := TStringList.Create; //Die Liste wird initialisiert.

    Try
      Try
        SL.Add(''); //Es wird eine neue Zeile hinzugefügt.
        For i := 1 to Length(S) do //Schleife über alle Zeichen des Terms
          Case S[i] of
            '0'..'9', ',', '.': Begin //Wenn Zeichen an Position i eine Zahl oder ein Komma ist,
              SL[SL.Count - 1] := SL[SL.Count - 1] + S[i]; //Dann füge es an eine schon bestehende Zahl an
            End;
            '*', '/', '+', '-': Begin //Rechenzeichen werden in eine eigene Zeile geschrieben
              If SL[SL.Count - 1] = 'Then Begin
                //Eventuell eine leere Zeile löschen (Wenn zwei Rechenzeichen hintereinander stehen
              SL.Delete(SL.Count - 1);
              End;
              SL.Add(S[i]); //Rechenzeichen hinzufügen
              SL.Add(''); //Zeilenumbruch einfügen (Damit die nächste Zahl eine eigene Zeile hat)
            End;
            Else Raise Exception.CreateFmt('Ungültiges Zeichen "%s" gefunden.', [S[i]]);
          End;


          {Ab hier wird gerechnet}
          begin
               begin
               i:=0; //Wir beginnen wieder am Anfang
               while i < SL.Count do
                  begin
                      if SL[i]='*then //Mal wird berechnet
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])*StrToFloat(SL[i+1])));
                               {Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???} 
                               SL.Delete(i);
                               {Jetzt soll die Zeile des Operators gelöscht werden} 
                               SL.Delete(i);{und die der zweiten Zahl} 
                               {etwas wurde gefunden - fange von vorn an} 
                               i := i-1;
                         end
                      else
                      if SL[i]='/then //Geteilt rechnen
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])/StrToFloat(SL[i+1])));
                               SL.Delete(i);
                               SL.Delete(i);
                               i := i-1;
                         end
                      else
                         i := i + 1;
                  end;
               i:=0; //Da es jetzt keine Punktrechnung mehr gibt, fangen wir wieder von vorne an und machen das Ganze mit + u.-
               while i < SL.Count do
                  begin
                      if SL[i]='+then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])+StrToFloat(SL[i+1])));
                               {Zahl vor und nach dem * werden multipliziert und in die Zeile der ersten Zahl geschrieben???} 
                               SL.Delete(i);
                               {Jetzt soll die Zeile des Operators gelöscht werden} 
                               SL.Delete(i);{und die der zweiten Zahl} 
                               {etwas wurde gefunden - fange von vorn an} 
                               i := i-1;
                         end
                      else
                      if SL[i]='-then
                         begin
                               SL[i-1]:=(FloatToStr(StrToFloat(SL[i-1])-StrToFloat(SL[i+1])));
                               SL.Delete(i);
                               SL.Delete(i);
                               i := i-1;
                         end
                      else
                         i := i + 1;
                  end;

                   
          end;
          end;
      Finally
            
        Result := SL[0]; //Am Ende ist dann nur noch eine Zeile übrig, die ist das Ergebnis
        end;
    Finally
      SL.Free; //Speicher der Liste wieder freigeben
    End;
end;

Der Aufruf für soetwas wäre dann z.B.

Edit1.text:=Rechnen(Edit2.text);

Der Term aus Edit2 wird berechnet und das Ergebnis wird in Edit1 ausgegeben
Das Ganze ist jetzt zwar funktionsfähig, versuch aber mal deinen eigenen zu basteln...

Liebe Grüße!
  Mit Zitat antworten Zitat