Frage

Was ist der klügste Weg, um einen Mathe-Parser zu entwerfen? Was ich meine, ist eine Funktion, die eine mathematische Zeichenfolge (wie: „2 + 3/2 + (2 * 5)“) nimmt und der berechnete Wert? Ich habe vor einem in VB6 Alter schreiben, aber es endete als Weg zu aufgebläht und nicht sehr portabel (oder Smart für diese Angelegenheit ...). Allgemeine Ideen, Pseudo-Code oder echten Code wird geschätzt.

War es hilfreich?

Lösung

Ein recht guter Ansatz wäre zwei Schritte umfasst. Der erste Schritt beinhaltet die Expression von Infix Umwandeln in Postfix (zB über Dijkstra Rangierbahnhof ) Notation. Sobald das erledigt ist, dann ist es ziemlich trivial, ein postfix Auswerter zu schreiben.

Andere Tipps

Ich schrieb ein paar Blog-Posts über einen mathematischen Parser zu entwerfen. Es gibt eine allgemeine Einführung , Grundkenntnisse über Grammatiken , Implementierung Probe geschrieben in Ruby und Testsuite . Vielleicht werden Sie diese Materialien nützlich finden.

Sie haben ein paar Ansätze. Sie könnten dynamische Code generieren und ausführen, um die Antwort zu erhalten, ohne viel Code schreiben zu müssen. Führen Sie einfach eine Suche auf Laufzeit generierten Code in .NET und es gibt viele Beispiele um.

Alternativ können Sie einen tatsächlichen Parser erstellen und ein wenig Parse-Baum erzeugen, die dann verwendet wird, um den Ausdruck auszuwerten. Auch das ist ziemlich einfach für einfache Ausdrücke. Schauen Sie sich Codeplex, wie ich glaube, dass sie auf ein Mathe-Parser haben. Oder nur BNF nachschlagen, die Beispiele umfassen wird. Jede Website Compiler Konzepte Einführung beinhaltet dies als ein einfaches Beispiel.

Codeplex Expression Evaluator

Ich weiß, das ist alt, aber ich kam in dieser versucht, einen Rechner als Teil eines größeren App zu entwickeln und auf einige Probleme lief die akzeptierte Antwort verwenden. Die Links waren sehr hilfreich für das Verständnis und die Lösung dieses Problems und sollte nicht unterschätzt werden. Ich habe eine Android-App in Java zu schreiben und für jedes Element in dem Ausdruck „string“ Ich eigentlich ein String in einer Arraylist während der Benutzer tippt auf der Tastatur gespeichert. Für die Infix-to-Postfix-Konvertierung, iteriert I durch jeden String in der Arraylist, bewerten dann die neu angeordneten Postfix Arraylist von Strings. Das war fantastisch für eine kleine Anzahl von Operanden / Betreiber, aber längere Berechnungen waren durchweg ab, zumal die Ausdrücke Auswertung zu nicht-Integer gestartet. In dem angegebenen Link für Infix zu Postfix Umwandlung , schlägt es knallte der Stapel, wenn der gescannte Artikel ist ein Operator und das topStack Element hat eine höhere Priorität. Ich fand, dass dies fast richtig ist. Popping das topStack Element, wenn es Vorrang ist höher oder gleich den gescannten Operator schließlich meine Berechnungen kommen richtig gemacht. Hoffentlich wird dies jemand helfen an diesem Problem zu arbeiten, und dank Justin Poliey (und fas?) Für einige wertvolle Verbindungen bereitstellt.

Wenn Sie eine „always on“ -Anwendung, Posten nur die Mathematik Zeichenfolge das Ergebnis Google und zu analysieren. Einfache Weise, aber nicht sicher, ob das, was Sie brauchen -. Aber klug in irgendeiner Weise ich denke

Die damit verbundene Frage Gleichung (Ausdruck) Parser mit Vorrang? hat einige gute Informationen auf, wie man damit begonnen, auch zu erhalten.

-Adam

Angenommen, Ihre Eingabe wird im String-Format ein Infix Ausdruck, man könnte es konvertieren postfix und ein Paar von Stapeln unter Verwendung: ein Operator-Stack und einen Operandenstapel, arbeitet, um die Lösung von dort. Sie können allgemeine Algorithmus Informationen auf dem Wikipedia-Link finden.

ANTLR ist ein sehr schönes LL (*) Parser-Generator. Ich empfehle es.

Entwickler wollen immer einen sauberen Ansatz haben, und versuchen, die Parsing-Logik von der Erde, bis in der Regel mit dem Dijkstra Rangier-Yard-Algorithmus . Ergebnis ist ordentlich Code suchen, aber möglicherweise gefahrenen mit Bugs. Ich habe eine solche API entwickelt, JMEP , dass alles, was der Fall ist, aber es hat mich Jahre haben stabilen Code.

Selbst mit all dieser Arbeit können Sie auch von dieser Projektseite sehen, dass ich ernsthaft zu wechseln, um mit JavaCC oder ANTLR bin am überlegen, auch nach allem, was Arbeit bereits getan.

11 Jahre in die Zukunft, wenn diese Frage gestellt wurde: Wenn Sie nicht das Rad neu erfinden wollen, gibt es viele exotische Mathe-Parser gibt.

Es ist eine, die ich vor Jahren geschrieben, die arithmetischen Operationen unterstützt, Gleichungslösung, Differentialrechnung, Integralrechnung, Basisstatistiken, Funktion / Formeldefinition, grafische Darstellung, etc.

Seine genannt ParserNG und es ist kostenlos.

Auswertung eines Ausdrucks ist so einfach wie:

    MathExpression expr = new MathExpression("(34+32)-44/(8+9(3+2))-22"); 
    System.out.println("result: " + expr.solve());

    result: 43.16981132075472

oder unter Verwendung von Variablen und Rechen einfache Ausdrücke:

 MathExpression expr = new MathExpression("r=3;P=2*pi*r;"); 
System.out.println("result: " + expr.getValue("P"));

oder mit den Funktionen:

MathExpression expr = new MathExpression("f(x)=39*sin(x^2)+x^3*cos(x);f(3)"); 
System.out.println("result: " + expr.solve());

result: -10.65717648378352

oder das Derivat an einem bestimmten Punkt zu bewerten (Beachten Sie es tut symbolische Differenzierung (nicht numerisch) hinter den Kulissen, so dass die Genauigkeit wird durch die Fehler der numerischen Approximation nicht beschränkt auf):

MathExpression expr = new MathExpression("f(x)=x^3*ln(x); diff(f,3,1)"); 
System.out.println("result: " + expr.solve());

 result: 38.66253179403897

Welche unterscheidet x^3 * ln(x) einmal bei x = 3. Die Anzahl der Zeiten, die Sie unterscheiden können, ist 1 für jetzt.

oder für Numerische Integration:

MathExpression expr = new MathExpression("f(x)=2*x; intg(f,1,3)"); 
System.out.println("result: " + expr.solve());

result: 7.999999999998261... approx: 8

Dieser Parser anständig schnell und hat viele andere Funktionen.

Die Arbeiten an der Portierung es zu Swift über Bindungen an Objective C abgeschlossen worden, und wir haben es genutzt Anwendungen unter anderem iterativen Anwendungsfällen in der grafischen Darstellung.

HAFTUNGSAUSSCHLUSS:. ParserNG wird von mir verfassten

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top