![]() |
Re: Taschenrechner - String durchsuchen
Zitat:
|
Re: Taschenrechner - String durchsuchen
So wie ich das sehe geht es nicht ohne eine Liste also Memo. Du musst den gesammten Term (also alles) sehen und dan auswerten wo die * und wo die + sind.
Dann nach und nach "auflösen" d.h. bei z.b. 5+5*5; So d.h. du musst erst mal alles sammeln, wenn ihr aber es in Schritten machen müsst, wir das meine Meinung nach wie schno gesagt nicht gehen. Gut mal ausgegangen du hast jetzt in einem Memo folgendes stehen:
Code:
So jetzt kannst du anfangen zu berechnen.
5
+ 5 * 5 Du musst jetzt wissen wo das * ist wegen Punkt vor Strich also in welcher Zeile. Dies bekommt man mit IndexOf von Memo.Lines (Lines ist die Liste, die ich in meinem Beispiel erstellt hatte) Damit bekommt du den Index das ist die Zeile. Diese merkst du dir dann. Mit dme Index -1 bekommst du dan die Zeile vor dem * also die Zahl. Und mit Index +1 die Zahl danach. Da String in Float umwandeln und berechnen lassen. Der Hacken ist aber jetzt, dass es sein kann das ja noch ein * oder so drinne ist.Deshalb eine Schleife, um alle * und so erstmal rauszufiltern. Danach das gleiche mit + und so. Also ohne eine Schleife wirst du wohl um es einfachzuhalten nicht darum kommen :angel: Und Jakob : Meiner Meinung nach ist deine Lösung noch komplizierter :mrgreen: Nicht böse gemeint nur dies ist noch komplexer mit Prozedure und Funktionen und was weis ich nicht alles :zwinker: |
Re: Taschenrechner - String durchsuchen
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! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz