Einzelnen Beitrag anzeigen

Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#1

erste Schritte zum Parser

  Alt 3. Dez 2006, 20:41
Hi,
bin heute auf einen Thread gestoßen wo jemand fragte wie man eine Rechnung in einem String berechnen kann. (Also '2+3/4' bspw). DIe Antwort war ein Mathe Parser und da ich etwas freizeit hatte hab ich mal angefangen einen zu entwickeln (ich weiss das es schon viele gibt, aber das hat denk ich mal noch keinen aufgehalten ).

Ich hab einfach mal angefangen simple Rechnungen zu lösen, erstmal ohne Klammern. Rausgekommen ist folgendes:

Delphi-Quellcode:
//Rechnungen ohne Klammern lösen
function TForm1.simplecalc(s:string):double;
var i:integer;
foo1,foo2:double;
temp:string;
ps:TPositionen;
begin
  temp:=s;

  //Punkt vor Strichrechnung
  calcpos(temp,ps); //Positionen der Operatoren festellen
  i:=0;
  while (i < length(ps)) and
  ((pos('*',temp)>0) or (pos('/',temp)>0)) do begin
    if (temp[ps[i]]='*') or (temp[ps[i]]='/') then begin
      //erster Faktor
      if i=0 then foo1:=strtofloat(copy(temp,1,ps[i]-1))
      else foo1:=strtofloat(copy(temp,ps[i-1]+1,ps[i]-ps[i-1]-1));
      //zweiter
      if i=length(ps)-1 then foo2:=strtofloat(copy(temp,ps[i]+1,length(temp)))
      else foo2:=strtofloat(copy(temp,ps[i]+1,ps[i+1]-ps[i]-1));

      //ergebnis
      if (temp[ps[i]]='*') then
      foo1:=foo1*foo2
      else foo1:=foo1/foo2;

      //an passender Stelle in den String einsetzen
      if i=0 then temp:=floattostr(foo1)+copy(temp,ps[i+1],length(temp))
      else if i=length(ps)-1 then temp:=copy(temp,1,ps[i-1])+floattostr(foo1)
      else temp:=copy(temp,1,ps[i-1])+floattostr(foo1)+copy(temp,ps[i+1],length(temp));

      showmessage(temp);
      
      calcpos(temp,ps);
     end;
     inc(i);
  end;

  //Additionen / Subtraktionen
  foo1:=strtofloat(copy(temp,1,ps[0]-1));
  for i:=0 to length(ps)-1 do begin
    if i=length(ps)-1 then
      foo2:=strtofloat(copy(temp,ps[i]+1,length(temp)))
        else foo2:=strtofloat(copy(temp,ps[i]+1,ps[i+1]-ps[i]-1));
    if temp[ps[i]]='+then foo1:=foo1+foo2
    else foo1:=foo1-foo2;
  end;

  //Ergebnis (foo1) ausgeben
  showmessage(floattostr(foo1));

end;
das ganze funktioniert zumindest schonmal. Was ganz klar noch nicht funktioniert ist:
- Klammersetzung, aber das hab ich bereits geschrieben
- Negative Zahlen eingeben (Nach dem Motto 1+-3, aber das kann man noch relativ leicht abfangen indem man -- zu +; +- und -+ zu - und ++ zu + macht.

Ich würde mal gern eure Meinung zu meinem Ansatz hören. Ich denke mal es ist nicht der eleganteste, aber was hätte ich wie besser machen können? Ich würd mich über Feedback sehr freuen

edit: noch kurz zum algorithmus: ich gehe so vor, das ich in der Rechnung erst alle Produkte löse, so dass ich nachher nur noch additionen und subtraktion haben.
Aus 1*2+3*4+5*6 wir so erstmal 2+3*4+5*6 , dann 2+12+5*6 und dann 2+12+30 was dann im zweiten schritt zu 44 wird

mfg
Antigo
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  Mit Zitat antworten Zitat