AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Term (Zeichenfolge 1+2*3) in Fließkommazahl

Ein Thema von Delphi-Narr · begonnen am 16. Sep 2009 · letzter Beitrag vom 10. Nov 2009
Antwort Antwort
Seite 5 von 5   « Erste     345
Benutzerbild von Delphi-Narr
Delphi-Narr

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

Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl

  Alt 23. Okt 2009, 15:39
Delphi-Quellcode:
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;
Hab das jetzt da stehen. Die erste Schleife kommt später noch, wird ja bei 1+2*3 nicht benötigt.
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)...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#42

Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl

  Alt 23. Okt 2009, 15:55
für sowas gibt es den Debuger ... da schaut man wo es knallt und auch gleich warum

da fällt dann auf, daß es hier knallt
Delphi-Quellcode:
SL.Delete(i);
SL.Delete(i+1); <<<
die aktuellen Werte sind da
Code:
i = 3

0: 1
1: +
2: 2
3: *
4: 3
Code:
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
ja und nun versuchts du SL.Delete(i + 1);
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)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von Delphi-Narr
Delphi-Narr

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

Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl

  Alt 23. Okt 2009, 16:22
Mit i:=i-1 geht's auch...
Danke für die Hilfe!
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#44

Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl

  Alt 23. Okt 2009, 17:09
Hallo,

man könnte das Problem auch mit einigen geschachtelten Routinen lösen:

Delphi-Quellcode:
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;
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.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.014 Beiträge
 
Delphi 12 Athens
 
#45

Re: Term (Zeichenfolge 1+2*3) in Fließkommazahl

  Alt 10. Nov 2009, 09:04
[nicht wichtig]

mathe parser

sind nur'n paar Stichworte für die Suchfunktion
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:45 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz