Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Strings Analysieren - C++ (https://www.delphipraxis.net/148694-strings-analysieren-c.html)

Maddin1 6. Mär 2010 13:56


Strings Analysieren - C++
 
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! :)

himitsu 6. Mär 2010 15:30

Re: Strings Analysieren - C++
 
Du zerlegst einfach den String an den Zahlengrenzen/Operatoren/Klammern

bei aufeinanderfolgenden Gruppen von
[stringanfang] [-/+] [zahl]
[operator] [-/+] [zahl]
[klammer] [-/+] [zahl]
ist das + oder - jeweils ein Vorzeichen und kein Operator, so daß du dieses wieder mit Zahl vereinen kannst

oder du prüfst gleich direkt beim Parsen, ob vor dem +/- keine Zahl oder eine schließende Klammer kam.

Maddin1 7. Mär 2010 13:28

Re: Strings Analysieren - C++
 
Okay Dankeschön für den Tipp.

Ich habe in der Abfrage nach den Binäroperatoren einfach
noch folgende Abfrage gemacht:
Code:
bool Minus=false; //Initialisierung der Flag-Variable zu Beginn der Funktion
if (String[i]=='-') if (i==1 || (i>1 && String[i-1]=='(')) {Opnd=Opnd+String[i];Minus=true;}
// darunter steht ja die weitere Abfrage, die folgendermaßen geändert wurde:
if (String[i]!=' ' && String[i]!=NULL)
         if (!Minus)Operator->Items->Add(String[i]);
          else Minus=false;

So, nur damit das hier auch vollständig ist^^
Klappt nun wunderbar, vielen Dank für den Ansporn :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:43 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-2025 by Thomas Breitkreuz