Autor Beitrag
harald mittermeier
Hält's aus hier
Beiträge: 5

Win XP, Kubuntu
Delphi
BeitragVerfasst: Mo 30.10.06 13:21 
Extended Math ist mein neues Delphi-Projekt derzeit.
Darstellen kann es
- rationale Funktionen,
- (einfache) gebrochenrationale Funktionen,
- Listen graphisch (--> Plottfunktion)
- ...

Ich habe für mein Programm eigens mehrere Prozeduren geschrieben, die
den String aus einem der fünf Editfelder Schritt für Schritt zerlegen,
bis ein Term wie "(x+3)*(x-8)/(x-5)"
zu z.B. "(1+3)*(1-8)/(1-5)", "(4*(-7))/(-4)", u.s.w. wird und dann
als einfache Division "28/4" berechenbar wird.

Es kann bei komplizierteren Funktionen notwendig sein, mehrere Klammern
zu verwenden, da die Prozedur von links nach rechts vorgeht und
gegebenenfalls die "Punkt-vor-Strich"-Regel nicht beachtet.

Ich bin für jede Anregung und (sachliche) Kritik offen.
Einloggen, um Attachments anzusehen!
Corpsman
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228

KUbuntu 10.4
Lazarus
BeitragVerfasst: Di 21.11.06 22:58 
Hallo,

Ich habe in meinem Loop Compiler ( www.loopcompiler.de.vu ) auch einen Mathe Parser gebaut.

Dieser Rechnet zwar nur mit Zahlen Element N aber das prinzip ist das selbe.

Ich bin damals hergegangen und habe das Ganze in einen Baum geparst den habe ich dann nachher mittels rekursivem Abstieg berechnen lassen können.

Der Parser Ging folgendermasen vor.

Data = String der die Eingegebene Formel enthält.

Es Folgt ein wenig PseudoCode
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
// Zuerst habe ich die Klammern ausgerechnet
If Pos(')',data)<> 0 then begin
// Ausgehend von der Gefundenen Position von ) weis ich das wenn ich im String nun nach Links gehe ich auf alle Fälle
// einen Inneren Klammerausdruck finde. Diesen Übergebe ich Rekursiv an meinen Formelparser und erhalte dann den Pointer
// den ich statt der Klammer eintragen kann.
end;

// Nachdem nun Alle Klammern Weg sind kann ich ganz normal Parsen, dabei gehe ich so vor das ich zuerst die Ausdrücke
// auflöse die die stärkere Bindung haben.

// also 

If Pos('*',data) <> then begin
// suche Zahl vor * 
// Suche Zahl Nach*
// Erzeuge neuen Pointer mit Rechenoperation * und den beiden Zahlen
// Schreibe ihn statt des gefundenen * hin
end;

// Dann wird weiter geparst mit  +, * , / , Mod , div ...

Das ganze Endet wenn am Schlus nur noch der daraus gebastelte Wurzelpointer im String steht.

ein Ausdruck wie etwa

1+2*3
wird dann zu
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
// Du siehst hier das Baumdiagramm, muste es als Quelltext formatieren, da sonst die Leerzeichen gelöscht werden.
      +  
    /  \
   1    *
      /  \
     2    3

Natürlich kann mein Parser X, y ,z auch. das ein zu bauen braucht aber dann LookUpTables.

_________________
--
Just Try it.