Rechnung lösen

mark87

Grünschnabel
Hallo,
ich bin noch ein Anfänger in Java. Gibt es irgendeine einfache Möglichkeit, Rechnungen wie 5+8*(10+2)+5^(2*5), die als String vorliegen, zu lösen. Wichtig wäre, das auch potenzen ("^") möglich sind.

Ich habe es schon Stundenlang selbst versucht, den String zu zerpflücken und mit substring und charAt die rechnungen rauszubasteln und zu lösen, aber wie ihr euch denken könnt ist das verdammt schwer, dass es nachher auch mit allen möglichen rechnungen funktioniert.

Gibt es da irgendeine einfachere Möglichkeit?

Vielen Dank
 
Zuletzt bearbeitet:
Moin und willkommen bei Tutorials.de ;)

wenn Dein Beispiel komplett als String vorliegt, dann wirst Du diesen wohl oder übel solange aufdröseln müssen, bis Du die einzelnen Komponenten, mit denen Du rechnen kannst (sollten dann in Zahlenwerte konvertiert sein), vorliegen!
Zur Ermittlung der mathematischen Zeichen wie '+', '*', '(', ')' oder '^' wirst Du Dir notgedrungen sowas wie eine eigene kleine Grammatik schrieben müssen oder ggf. können Dir hier auch reguläre Ausdrücke helfen!
Eine gute Übersicht hierfür liefert diese Seite:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html

Gruß
Klaus
 
Beim ANTLR Parser Generator ist ein entsprechendes Beispiel (Expression Evaluator) auf der Seite http://www.antlr.org/wiki/display/ANTLR3/FAQ+-+Getting+Started zu finden.

Achso noch einfacher wäre es einen Javascript Interpreter zu verwenden:
Java:
// create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a JavaScript engine
        ScriptEngine engine = factory.getEngineByName("JavaScript");
        // evaluate JavaScript code from String
        Object result = engine.eval("5+8*(10+2)+5^(2*5)");
        System.out.println(result);
 
@zeja: Das funktioniert leider mit den Hochzahlen leider nicht.

@vfl_freak: Vielen Dank. Die Seite hilft mir schon sehr.

Jedoch wundere ich mich, dass es sowas nicht bereits gibt. Ich bin doch wohl kaum der erste der das Problem hat. Gibts da nicht schon was fertiges?

Gruß
 
Danke, aber das hilft mir leider nicht. Es geht mir nicht darum "nur" Potenzen zu berechnen, sonder komplexere Terme in denen Potenzen enthalten sind wie "5+8*(10+2)+5^(2*5)".

Gruß
 
Jedoch wundere ich mich, dass es sowas nicht bereits gibt. Ich bin doch wohl kaum der erste der das Problem hat. Gibts da nicht schon was fertiges?

Moin,

nein, denke ich nicht - oder besser gesagt: dass sind dann eben bspw. die genannten regulären Ausdrücke! Weil - vielmehr ist es ja mathematisch gesehen auch nicht ! !

Oder Du schreibst Dir halt Deine eigene, spezielle Grammatik, die alle Besonderheiten Deiner Termini berücksichtigt!

Gruß
Klaus

Gruß
Klaus
 
Hallo,

Ich würde da eher über Rekursivität rangehen.

Sprich du läufst den String Zeichen für Zeichen von hinten nach vorne durch und wenn du einen Strichoperator (+ -) findest, der nicht in Klammern steht, führst du den Rechenweg für den Substring Links und Rechts vom Operator durch und addierst bzw. subtrahierst die Rückgabewerte und gibst das Ergebnis über return zurück.
Für die Klammern würde ich einen int-Wert benutzen, der die Klammernebene angibt. Bei ) würde der dann um 1 erhöht werden und bei ( wiederrum um 1 erniedrigt.
Findet er bei diesem Durchlauf keine Strichoperatoren kannst du nun die gleiche Prozedur auf Punktoperatoren (* /) anwenden.
Dann wiederum noch einmal ein Druchlauf für höhere Punktopderatoren (^).
Wenn er nun alle Schleifen durchlaufen hat, heißt es der String ist nur noch eine Zahl oder steht in Klammern.
Die Zahl kann man ganz normal parsen. Für den Klammerusdruck widerrum, führt man einfach nochmal einen rekursiven Aufruf durch mit den Substring ohne die Klammern.

Bei deinem Beispiel 5+8*(10+2)+5^(2*5) würde er nun so aufteilen:
5^(2*5)
_5
_(2*5)
__2*5 <-- multipliziert die Rückgabewerte (2.0 und 5.0)
___2 <-- kann ganz normal geparsed werden mit Double.parseDouble(String); gibt also 2.0 zurück
___5
5+8*(10+2)
_5
_8*(10+2)
__8
__(10+2)
___ 10+2
____10
____2

Hinweis: Dieser Weg ist zwar schnell, aber nur zu empfehlen bei kurzen Rechnungen. Bei längeren Rechnungen kann es passieren, dass kein Speicher mehr für rekursive Aufrufe zur Verfügung steht.
 
Zuletzt bearbeitet:
Hallo,

es wurde weiter oben schon mal die Frage gestellt, ob sowas nicht schon irgendeine API kann ...
Was wäre mit einer Excel-API?
Kann man da den String nicht als Formel in eine Zelle schreiben und Excel die Arbeit des Rechnens überlassen?
Es kommt natürlich darauf an, wofür und für welchen Zweck dein Programm benutzt wird. Dies wäre aber doch ein möglicher Workaround, oder?

Dass das Ganze innerhalb Java schöner ist, möchte ich aber noch mal betonen! :)


Gruß
Gerrit
 
Zurück