Umgekehrte polnische Notation in Java?

1 Antwort

Was ist denn unklar? RPN ist für solche Übungsbeispiele beliebt, gerade weil sie extrem einfach umzusetzen ist. Infix-Notation ist da viel umständlicher.

Mühsam ist bei sowas meist das Parsen der Eingabe und ggf. sinnvolle Fehlerbehandlung.

Ein ganz simpler Rechner für Ganzzahlen könnte z.B. so umgesetzt werden.

var input = "5 3 + 6 2 - *";

Map<String, BinaryOperator<Integer>> ops =
    Map.of(
        "+", (a, b) -> b + a,
        "-", (a, b) -> b - a,
        "*", (a, b) -> b * a,
        "/", (a, b) -> b / a);

var stack = new ArrayDeque<Integer>();
for (String token : input.strip().split("\\s+")) {
  if (ops.containsKey(token)) {
    stack.addFirst(ops.get(token).apply(stack.removeFirst(), stack.removeFirst()));
  } else {
    stack.addFirst(Integer.valueOf(token));
  }
}

System.out.println(stack.removeFirst());

Fehlerbehandlung "left as an exercise for the reader".

Lamanini  05.11.2023, 15:08

Ja, Regex Pattern matching und Maps versteht sicher jemand, der noch ganz am Anfang ist, und die Grundlagen lernt.

Das hilft doch nicht.

0
jo135  05.11.2023, 15:19
@Lamanini

Ganz am Anfang? Woher weißt du das?

Um String.split() - und damit grundlegende Regexes - wird FS hier nicht herumkommen, wenn die Eingabe als einzelner String erfolgt.

Maps sind eine der grundlegendsten Datenstrukturen überhaupt und sollten jemanden, der hier zwangsläufig mit Stacks arbeiten muss, auch nicht groß überfordern.

Sie sind hier aber nichtmal so wichtig: der Kern dieses hochkomplexen Progrämmchens ist das schrittweise Abarbeiten der in Tokens zerlegten Eingabe und die Entscheidung, ob man das aktuelle Token auf den Stack wirft (weil Zahl) oder als Operator auf die obersten Stack-Elemente anwendet.

Ob man das dann per Map oder Switch oder gar einem langen If-Else-Konstrukt macht, ist wieder zweitrangig.

0
Lamanini  05.11.2023, 15:52
@jo135
Ganz am Anfang? Woher weißt du das?

Weil seine Aufgabe daraus besteht, einen Taschenrechner mit den grundlegendsten Operationen in einer extrem einfachen Notation umzusetzen?

Ich betreue immer mal wieder ein paar Studenten und das ist so erstes Semester erste paar Vorlesungen. Da kennt man vielleicht gerade so Schleifen und ifs.

Um String.split() - und damit grundlegende Regexes

Das geht damit nicht einher, Regex ist sehr komplex, gerade am Anfang.

Maps sind eine der grundlegendsten Datenstrukturen überhaupt und sollten jemanden, der hier zwangsläufig mit Stacks arbeiten muss, auch nicht groß überfordern.

Wenn man als Anfänger eine Map von strings auf binäre Operatoren sieht in einer Lambda-Schreibweise schaltet man ab. Was ist überhaupt eine solche Funktion? Wie funktioniert die Schreibweise? Das weiß man als Anfänger nicht.

schrittweise Abarbeiten der in Tokens zerlegten Eingabe und die Entscheidung, ob man das aktuelle Token auf den Stack wirft (weil Zahl) oder als Operator auf die obersten Stack-Elemente anwendet.

Was als Anfänger nicht ersichtlich ist. Wenn man mit dem Auge dem Codefluss nicht sofort einfach folgen kann überfordert das einen.

Ob man das dann per Map oder Switch oder gar einem langen If-Else-Konstrukt macht, ist wieder zweitrangig.

Ich bin mir sicher du hast nie Probleme neuen Code mit neuen Syntax-Strukturen zu verstehen.

0
jo135  05.11.2023, 16:15
@Lamanini
Was als Anfänger nicht ersichtlich ist. Wenn man mit dem Auge dem Codefluss nicht sofort einfach folgen kann überfordert das einen. ... Ich bin mir sicher du hast nie Probleme neuen Code mit neuen Syntax-Strukturen zu verstehen.

Weißt du was? Ich habe in meinem Leben schon viele Sprachen erlernt (zum Programmieren und zur menschlichen Verständigung), und tatsächlich kann man das am besten machen, indem man meist leicht und manchmal deutlich überfordert wird. Man lernt, die noch nicht bekannten Konstrukte zu überspringen oder deren Funktion zumindest grob zu vermuten. Man geht den Code schrittweise immer wieder durch, gern auch im Debugger, und lernt daraus immer genauer, was wann passiert. Mit der Zeit fällt's immer leichter, aber man muss es halt üben.

Du musst keine Lambda-Notation im Detail verstehen, um grob zu vermuten dass hier offenbar irgendwie von Strings auf mathematische Operationen übersetzt wird. Du musst nicht fähig sein eine komplexe Regex zu schreiben, um String.split() zu verwenden, aber die Grundzüge erfordert das API halt (man kann natürlich auch selbstüberschätzender Masochist sein und das Tokenisieren selber basteln, aber ob das wirklich einfacher ist?).

Jeder Student sitzt anfangs vor Aufgabenblättern und Skripten, die komplett überfordern. Man versteht erstmal wirklich nur Bahnhof. Man muss sich zwingen, langsam und in kleinen Schritten zu lernen, sozusagen in Zeitlupe. Kein rasches Überfliegen. Das ist für die Generation TikTok sicher besonders schwierig, aber irgendwann muss man damit anfangen.

Mein Beispiel illustriert vor allem, dass die Sache offenbar nicht ganz so schwierig und umfangreich ist, wie sie FS erscheint: mehr als ein paar Ifs und eine(!) Schleife ist da eigentlich nicht. Die Lösung kann auch länger ausfallen, aber die Logik ist simpel. Es ist ja eben nicht meine Intention, die Hausaufgaben für FS zu machen - wenn er oder sie dieses Beispiel verbatim abgibt ohne es erklären zu können, wird das schief gehen.

Leider verrät FS halt auch nicht, ob es eher am Verständnis der Logik oder an Sprachspezifika hapert.

0
lucca278 
Fragesteller
 05.11.2023, 16:46

Hallo, Danke ! ja also das hilft mir schon ein großes Stück weil ich nicht wusste wie ich die Eingabe zerlegen und damit weiter vorgehen soll. Stack haben wir schon besprochen und verwendet aber nicht ArrayDeque. Werde es natürlich nicht genauso abgeben LOL

0