Wie bewerten Sie einen Ausdruck in der Präfix-notation
Ich versuche zu bewerten, eine Liste das ist ein Ausdruck in der Präfix-notation. Hier ist ein Beispiel für eine solche Liste:
[+, [sin, 3], [- 10 5]]
Was ist der beste Weg zu bewerten, den Wert der Liste
Ist dieses Hausaufgaben?
warum müssen Sie Klammern dann?
Wenn es ausgedrückt werden kann mit Rekursion kann ausgedrückt werden mit einem stack.
Nein, es ist keine Hausaufgaben - ich bin versucht zu implementieren, Karl-Sim-genetische Programmierung, Technik (karlsims.com/papers/siggraph91.html), die verwendet Lisp-s-Ausdrücke in python.
Einfach nur neugierig, @ad126 -- haben Sie dies getan, in python ? Kann man teilen, oder zeigen Sie mir jeden Quellcode für diese genetische Programmierung, Technik ? Dank
warum müssen Sie Klammern dann?
Wenn es ausgedrückt werden kann mit Rekursion kann ausgedrückt werden mit einem stack.
Nein, es ist keine Hausaufgaben - ich bin versucht zu implementieren, Karl-Sim-genetische Programmierung, Technik (karlsims.com/papers/siggraph91.html), die verwendet Lisp-s-Ausdrücke in python.
Einfach nur neugierig, @ad126 -- haben Sie dies getan, in python ? Kann man teilen, oder zeigen Sie mir jeden Quellcode für diese genetische Programmierung, Technik ? Dank
InformationsquelleAutor ad126 | 2010-07-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wird es einfacher sein, wenn Sie verwendet postfix statt Präfix. Sehen Die umgekehrte polnische Notation (RPN). Gegeben ein Ausdruck in RPN, ist es leicht zu bewerten, dass mit nur einem stack.
Aber da du gefragt für einen Weg zu bewerten Präfix Ausdrücken ohne Rekursion und Verwendung von stacks (für einen evtl. einfacheren Weg, siehe EDIT: weiter unten), hier ist eine Möglichkeit:
Wir können dies tun, mit zwei stacks.
Einem stack (call-it-Evaluation) hält den Operatoren (wie +, sin etc) und Operanden (wie 3,4 etc) und der andere Stapel (nennen wir ihn Graf) hat ein Tupel in der Anzahl der Operanden, die Links zu sehen + die Anzahl der Operanden eines operators erwartet.
Wenn Sie sehen einen operator, drücken Sie den Betreiber auf die Auswertung stack und drücken Sie die entsprechende Tupel auf der Graf-stack.
Jederzeit sehen Sie einen Operanden (wie 3,5 etc), überprüfen Sie die top-Tupel der Count-stack und dekrementiert die Anzahl von Operanden, die Links zu sehen ist, dass Tupel.
Wenn die Anzahl der Operanden, die Links zu sehen null wird, wird Sie aus dem pop-Tupel aus der Count-stack. Dann von der Evaluation stack pop Sie aus der Anzahl der Operanden erforderlich (Sie weiß das, weil der andere Wert der Tupel), pop-off der Betreiber und die operation erhalten Sie einen neuen Wert ein (oder Operanden).
Nun schieben Sie das neue Operanden zurück auf die Evaluation stack. Diese neue operand push bewirkt, dass Sie zu einem anderen Blick auf die Spitze der Graf Haufen und Sie tun die gleiche Sache, die wir gerade haben (dekrementiert den Operanden gesehen, zu vergleichen mit null etc.).
Wenn der operand count nicht zu null, fahren Sie mit dem nächsten token in der Eingabe.
Zum Beispiel sagen Sie zu bewerten hatte + 3 + 4 /20 4
Die Stapel Aussehen wird (Links ist oben auf dem stack)
EDIT:
Einem Freund vorgeschlagen, einen Weg, dies zu tun ohne mehrere stacks:
Anfang vom Ende, gehen Sie zu den ersten operator. Die tokens auf die Rechte Seite, wird Operanden. Auswerten und wiederherstellen. Scheint viel einfacher als es zu tun mit zwei stacks. Können wir eine doppelt verkettete Liste darstellen, die Eingabe, das ändern wir während der Verarbeitung. Wenn Sie auswerten möchten, löschen Sie den Knoten, und legen Sie dann das Ergebnis. Oder man könnte vielleicht einfach ein stack.
Es könnte schwierig werden, da nur Rückwärtsfahren einmal nicht tun. Sie haben, um zu konvertieren jede Unterliste zu. Wenn Sie zu tun haben, (d.h. Sie können nicht vermeiden, Präfix), Sie könnte genauso gut verwenden Sie die oben genannten one-pass-Algorithmus, anstatt zu versuchen, zu konvertieren, zu postfix und verwenden Sie dann den RPN-Bewerter.
Wort, Idiot. Vielen Dank für Ihre Hilfe.
Ein Freund schlug vor, ein einfacher Weg, finden Sie vielleicht leichter zu implementieren (obwohl ich habe nicht versucht, zu überprüfen, Richtigkeit). Habe ich editiert, die Antwort zu enthalten, dass (und könnte eigentlich auch sein, was Paulus sagen wollte).
InformationsquelleAutor
KISS, bewerten in umgekehrter als postfix-Ausdruck.
InformationsquelleAutor paul
So wie ich das sehe hast du zwei Optionen. Gehen Sie entweder Links nach rechts oder von rechts nach Links (wie Paulus es oben vorgeschlagen). Beide Methoden werden im folgenden code dargestellt.
Einige tests:
InformationsquelleAutor Ohad Schneider