Ich bin gerade dabei, von Java zu Python überzugehen und habe die Aufgabe übernommen, einen Rechner zu erstellen, der symbolische Operationen mit mathematischen Formeln ausführen kann ( ohne benutzerdefinierte Module wie Sympy ) ). Derzeit ist es so konstruiert, dass Zeichenfolgen akzeptiert werden, die durch Leerzeichen getrennt sind und nur die Operatoren (,), +, -, * und / ausführen können. Leider kann ich den grundlegenden Algorithmus zur Vereinfachung der symbolischen Ausdrücke nicht herausfinden.
Wenn Sie zum Beispiel die Zeichenfolge '2 * ((9/6) + 6 * x)' eingeben, sollte mein Programm die folgenden Schritte ausführen:
Aber ich kann das Programm nicht dazu bringen, das x zu ignorieren, wenn ich die 2. verteile. Wie kann ich außerdem mit 'x * 6 / x' umgehen, so dass es nach der Vereinfachung '6' zurückgibt?
EDIT: Zur Klarstellung, mit "symbolisch" meinte ich, dass es bei der Ausführung der restlichen Berechnungen Buchstaben wie "A" und "f" belassen wird.
EDIT 2: Ich habe den Code (meistens) beendet. Ich poste es hier, wenn jemand in der Zukunft auf diesen Post stößt, oder wenn jemand von euch neugierig ist.
%Vor%Sie müssen viel mehr verarbeiten, bevor Sie mit Symbolen arbeiten. Das Formular, das Sie erhalten möchten, ist ein Baum von Operationen mit Werten in den Blattknoten. Zuerst müssen Sie einen Lexer-Lauf für die Zeichenfolge ausführen, um Elemente zu erhalten. Wenn Sie jedoch immer durch Leerzeichen getrennte Elemente haben, reicht es möglicherweise aus, die Zeichenfolge zu teilen. Dann müssen Sie das Token-Array mit der benötigten Grammatik parsen.
Wenn Sie theoretische Informationen über Grammatiken und das Parsen von Text benötigen, beginnen Sie hier: Ссылка Wenn Sie etwas praktischeres brauchen, gehen Sie Ссылка (Sie müssen das Pypar-Modul selbst nicht verwenden, aber die Dokumentation enthält viele interessante Informationen) oder Ссылка
Von 2 * ( ( 9 / 6 ) + 6 * x )
müssen Sie zu einem Baum wie folgt gelangen:
Dann können Sie jeden Knoten besuchen und entscheiden, ob Sie ihn vereinfachen möchten. Konstante Operationen sind die einfachsten zu eliminieren - berechne einfach das Ergebnis und tausche den "/" Knoten mit 1.5 aus, weil alle Kinder Konstanten sind.
Es gibt viele Strategien, um fortzufahren, aber im Wesentlichen müssen Sie einen Weg finden, durch den Baum zu gehen und ihn zu modifizieren, bis nichts mehr zu ändern ist.
Wenn Sie das Ergebnis dann ausdrucken möchten, gehen Sie einfach den Baum erneut und erzeugen Sie einen Ausdruck, der es beschreibt.
Wenn Sie Ausdrücke in Python analysieren, sollten Sie die Python-Syntax für die Ausdrücke in Erwägung ziehen und sie mit analysieren ast
Modul (AST = abstrakter Syntaxbaum).
Die Vorteile der Verwendung der Python-Syntax: Sie müssen keine separate Sprache für diesen Zweck erstellen, der Parser ist integriert, ebenso der Evaluator. Nachteile: Es gibt eine Menge zusätzliche Komplexität in der Parse-Struktur, die Sie nicht benötigen (Sie können einige davon vermeiden, indem Sie die integrierten NodeVisitor
- und NodeTransformer
-Klassen für Ihre Arbeit verwenden).
Hier ist eine Beispielklasse, die einen Python-Syntaxbaum durchläuft und eine rekursive konstante Faltung (für binäre Operationen) durchführt, um Ihnen die Art von Dingen zu zeigen, die Sie ziemlich leicht machen können.
%Vor%