2016-09-30 5 views
0

In einem Codierungsproblem Auswertung ich seit einiger Zeit arbeiten jetzt habe, habe ich zu einem Schritt kommen, wo ich einen mathematischen Ausdruck zu bewerten haben, die wie folgt aussieht:einen mathematischen Ausdruck in C++

3 * 2^3^2 * 5 

und sollte wie folgt bewertet werden:

3 * 2^3^2 * 5 = 3 * 2^(3 * 2) * 5 = 3 * 64 * 5 = 960. 

In der aktuellen Form meiner Implementierung, ich zwei Vektoren haben, enthält man die Operanden als ganze Zahlen, während die andere die Operatoren als Zeichen enthält. Für den aktuellen Fall wären dies: vector<int> operands = { 3, 2, 3, 2, 5 } und vector<char> operators = { '*', '^', '^', '*' }.

Dies ist nur ein Beispiel, die Reihenfolge der Operationen kann sich in dem Sinne unterscheiden, dass die Multiplikation nicht immer die erste/letzte durchgeführte Operation ist.

Ich bin seit einiger Zeit an diesem speziellen Schritt fest, nämlich den von den beiden Vektorcontainern gekapselten Ausdruck zu einer ganzen Zahl zu bewerten. Ich habe mir einige mathematische Parser angeschaut, die ich im Internet finden konnte, aber ich sehe immer noch nicht, wie man eine korrekte Auswertung durchführt.

Eine Lösung würde sehr geschätzt werden.

enter image description here

+1

Meinst du wirklich '2^(3 * 2)' und nicht '2^(3^2)'? –

+1

Nein, das ist eigentlich der Ausdruck, den das Problem auferlegt, könnte nicht viel dagegen tun. 2^3^2 sollte als 2^(3 * 2) = 2^6, allgemeiner y^x1^x2^...^xn = y^(x1 * x2 * .... * xn) betrachtet werden. – user43389

+0

@ user43389 Nein, 2^3^2 sollte als 2^(3^2), = 2^9 = 512 ausgewertet werden, und beachten Sie, dass es rechtsassoziativ ist. Was du geschrieben hast ergibt keinen Sinn. – EJP

Antwort

1

Berechnen Sie einfach den Wert, während Sie den Ausdruck analysieren, wobei Sie eine Variable für das Endprodukt und eine für den aktuellen Multiplikanden (d. H. Die aktuelle Gruppe von Exponenten mit der entsprechenden Basis) beibehalten. Wenden Sie jeden exponentiellen Operanden sequenziell an, so wie Sie ihn sehen, und führen Sie so eine linksassoziative Exponentiation durch.

Nebenbei würde ich nicht den gesamten Ausdruck in einer Art vektorisierten Format speichern; Ich sehe keinen brauchbaren Grund dafür.

+0

Genau das habe ich getan (in Bezug auf das Denken), aber ich habe die Implementierung irgendwie durcheinander gebracht (es funktioniert nur bei dem gegebenen Testfall). Gut zu wissen, dass dies der richtige Weg ist, eine Implementierung wäre wirklich schön, wenn Sie Zeit hätten. Vielen Dank – user43389

+0

@ user43389 In welchen Testfällen schlägt Ihre Implementierung fehl? Da das gesamte Links-Assoziativitätsproblem im ursprünglichen Problem ** nicht ** erwähnt wird und wir nur annehmen, dass dies für die Lösung auf der Grundlage des Testfalls selbst erwartet wird, ist es durchaus möglich, dass * der Beispieltest Fall * ist einfach falsch. –

+0

Leider sind die Testfälle versteckt. Aber basierend auf der Anzahl der erfolgreichen Einreichungen von anderen Leuten, denke ich, dass das Problem tatsächlich machbar ist, selbst wenn man seinen schlecht geschriebenen Text betrachtet. – user43389

1

Was Sie möchten, ist möglich mit expression templates. Sie ermöglichen es, Ausdrücke in Nicht-Standard-Reihenfolge und/oder Verhalten zu bewerten - mit ihnen können Sie auch mehrere Bedeutungen für den gleichen Operator in einem Ausdruck definieren.

Verwandte Themen