![]() |
Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl
Delphi-Quellcode:
Hab das jetzt da stehen. Die erste Schleife kommt später noch, wird ja bei 1+2*3 nicht benötigt.
Function TForm1.ParseAndCalc(Const S: String): String;
Var SL: TStringList; i: Integer; Begin SL := TStringList.Create; Try Try SL.Add(''); For i := 1 to Length(S) do Case S[i] of '0'..'9', ',', '.': Begin SL[SL.Count - 1] := SL[SL.Count - 1] + S[i]; End; '*', '/', '+', '-': Begin If SL[SL.Count - 1] = '' Then Begin // eine leere Zeile kommt vor, wenn mehrere Operatoren // hintereinander liegen, z.B. bei '1*+2' bzw. '1 * +2' SL.Delete(SL.Count - 1); End; SL.Add(S[i]); SL.Add(''); End; ' ': ; // ignoriere Leerzeichen Else Raise Exception.CreateFmt('Ungültiges Zeichen "%s" gefunden.', [S[i]]); End; begin begin i:=0; 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+1);{und die der zweiten Zahl} {etwas wurde gefunden - fange von vorn an} 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+1); i := -1; end else i := i + 1; end; i:=0; 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+1);{und die der zweiten Zahl} {etwas wurde gefunden - fange von vorn an} 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+1); i := -1; end else i := i + 1; end; end; end; Finally Result := ''; For i := 0 to SL.Count - 1 do Result := Result + SL[i]; End; Finally SL.Free; End; End; Ich klick auf = und krieg die Meldung: Der Index der Liste überschreitet das Maximum (2). Vorher hatte ich immer die Meldung: Der Index der Liste überschreitet das Maximum(Anzahl der Zeilen der Stringlist)... |
Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl
für sowas gibt es den Debuger ... da schaut man wo es knallt und auch gleich warum :zwinker:
da fällt dann auf, daß es hier knallt
Delphi-Quellcode:
die aktuellen Werte sind da
SL.Delete(i);
SL.Delete(i+1); <<<
Code:
i = 3
0: 1 1: + 2: 2 3: * 4: 3
Code:
ja und nun versuchts du SL.Delete(i + 1);
0: 1
1: + 2: 6 << durch SL[i-1]:=...; geändert << der alte Wert an Index 3 wurde durch SL.Delete(i); gelöscht 3: 3 << hat jetzt den Index 3 und nicht mehr 4 i+1 = 4 und die 4 gibt es nicht mehr ... also da auch nur SL.Delete(i); PS: das i := -1; ist jetzt falsch, da war, bevor ich dort mal das ELSE einfügt, denn vorher wurde nach der Schleife das i:=i+1; noch mit ausgeführt und -1+1=0 ... also der Anfang, aber wegen des Else muß da jetzt auch stattdessen i:=0; hin (hab es oben mal editiert) |
Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl
Mit i:=i-1 geht's auch...
Danke für die Hilfe! |
Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl
Hallo,
man könnte das Problem auch mit einigen geschachtelten Routinen lösen:
Delphi-Quellcode:
In der jetzigen Form verarbeitet der Parser nur Integer-Ausdrücke, die Fehlerbehandlung verdient ihren Namen eigentlich nicht. Aber es soll ja lediglich das Prinzip verdeutlicht werden.
function Eval (s: string): Integer;
function EatChar (const aSet: TSysCharSet; var ch: Char): Boolean; begin Result := ((s <> '') and (s[1] in aSet)); if Result then begin ch := s[1]; s := TrimLeft(Copy(s, 2, MaxInt)); end; end; function Term: Integer; function Summand: Integer; function Factor: Integer; var ErrPos: Integer; op: Char; begin if EatChar(['+', '-', '('], op) then case op of '+': Result := Factor; '-': Result := -Factor; '(': begin Result := Term; if (not EatChar([')'], op)) then raise Exception.Create('missing ")"'); end; else Result := 0; // calm compiler end else begin Val (s, Result, ErrPos); if (ErrPos = 0) then s := '' else s := TrimLeft(Copy(s, ErrPos, MaxInt)); end; end; var op: Char; begin Result := Factor; while EatChar(['*', '/'], op) do case op of '*': Result := Result * Factor; '/': Result := Result div Factor; end; end; var op: Char; begin Result := Summand; while EatChar(['+', '-'], op) do case op of '+': Result := Result + Summand; '-': Result := Result - Summand; end; end; begin s := Trim(s); Result := Term; if (s <> '') then raise Exception.Create('unknown operation'); end; Gruß Hawkeye |
Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl
[nicht wichtig]
mathe parser sind nur'n paar Stichworte für die Suchfunktion |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:16 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 by Thomas Breitkreuz