Hallihallo ihr Lieben.
Wir sollen zurzeit für den Informatik Unterricht eine Facharbeit schreiben,
in der wir einen Formel-Parser mit C++ entwerfen sollen.
Das ganze dann über Listen und Binärbäume.
Das wichtigste zu Anfang dafür ist jedoch ein
fehlerfreies zerlegen der eingegebenen Funktion als String.
Ich habe bereits damit angefangen, doch leider
ist es noch nicht ganz so, wie es sein sollte:
Es müssen nämlich auch negative Zahlen beachtet werden
(ein extra Vorzeichen für positve Zahlen soll vernachlässigt
werden).
Das Problem ist jetzt, wie ich negative Zahlen als
Zahlen herausfiltere, anstatt das Minus vor der Zahl
als Operator interpretiere. Natürlich könnte man es auch
generell als Vorzeichen interpretieren lassen und
als Addition einer negativen Zahl wieder zusammenfügen,
aber das sollte laut Informationen des Lehrers nicht so erfolgen.
Ich habe mir schon überlegt mit einer Flag-Variable zu arbeiten,
um herauszufinden ob das letzte Zeichen ein Operand oder ein '('
ist, oder man sogar noch am Anfang des Strings ist.
Bin mir aber nicht so sicher, ob das das beste wäre.
Ich trenne im folgenden Quellcode Operatoren und Operanden
in zwei ListBoxen. Jedoch gibt es leere Zeilen,
wenn zwei Operatoren aufeinander treffen, wie zum Beispiel "(-".
Ich wollte euch nun fragen, ob ihr vielleicht Tipps für mich
hättet zum Lösen des Problems oder zur Verbesserung der anfänglichen
Analyse.
Code:
#define UniOp (Opnd!="sin" && Opnd!="cos" && Opnd!="tan" && Opnd!="sqrt")
#define BinOp (String[i]=='(' || String[i]==')' || String[i]=='+' || \
String[i]=='-' || String[i]=='*' || String[i]=='/' || String[i]=='-' || String[i]=='^' )
void Analyse(AnsiString String, TListBox *Operand, TListBox *Operator)
{ AnsiString Opnd="", Optr=""; //Strings initialisieren
for (int i=1; i <= String.Length(); i++) {
if (String[i]<='9' && String[i]>='0' || String[i]==',')
Opnd=Opnd+String[i]; //Operand aufbauen
else
if (String[i]>='a' && String[i]<='z')
Opnd=Opnd+String[i]; //Operand aufbauen - Variablen (oder Operatoren wie sin, cos)
else {
if (Opnd!="") {if UniOp Operand->Items->Add(Opnd); //auf
//sin, etc prüfen
else Operator->Items->Add(Opnd); Opnd="";}
if BinOp { //auf +, -, etc prüfen
if (String[i]!=' ' && String[i]!=NULL) Operator->Items->Add(String[i]);
}else if (String[i]!=' ' && String[i]!=NULL) {Operand->Items->Add(Opnd);Opnd="";}
}
}
if (Opnd!="") Operand->Items->Add(Opnd); // letzes Zeichen ausgeben
}
Vielen Dank für eure Hilfe!