Dies ist die abschließende Aufgabe aus der Reihe "Aus klein mach groß" und basiert auf
"Aus klein mach groß": Teil3 - Rechnen mit Zahlen
"Aus klein mach groß": Teil2 - Zahlen und Satzzeichen
sowie
"Aus klein mach groß": Teil1 - Stack
Wie auch vorher richtet es sich primär an Anfänger - deshalb sind die Anforderungen und Grenzen etwas "enger" gesteckt.
Teilaufgabe a)
Infixterm nach Postfix (UPN) umwandeln.
wir alle kennen Infixnotation für "normale" Rechenvorgänge:
1+2+4 oder (2+3)*(6+7)
Infixnotation heißt eigentlich, dass Operatoren(+*-) zwischen den Operanden stehen: 1+2
Hier "Aus klein mach groß": Teil3 - Rechnen mit Zahlen haben wir schon eine andere Notation kennengelernt und auch gesehen, dass das Abarbeiten solcher "Rechenanweisungen" in der UPN Notation programmiertechisch vergleichsweise einfach umgesetzt werden kann. Die Programme aus "Aus klein mach groß": Teil3 - Rechnen mit Zahlen können Benutzereingaben in solcher Form entgegennehmen und ausrechnen. Allerdings ist es für den Benutzer sehr gewöhnungsbedürftig, seine Terme erstmal in diese Form zu bringen - das wollen wir jetzt "übernehmen"
.
Programmiere also ein Modul, welches "normale" Infixeingaben in UPN Form bringt und als String zurückgibt. Dazu kann man "Aus klein mach groß": Teil2 - Zahlen und Satzzeichen entsprechend erweitern/anpassen.
Jetzt muss man aber dararuf achten, dass alle Zahlen korrekt eingegeben werden - uneindeutige Eingabeformen wie 123.123.132 sollten mit einer Fehlermeldung (am besten mit dem genaueren Stellenhinweis) quittiert werden, da der Benutzer durchaus 123.123+.123 gemeint haben könnte und sich vertippt hat.
Weiterhin muss man die Prioritäten der einzelnen Rechenzeichen beachten: - * / vor + - und () sind "am mächtigsten"
akzeptiert werden sollten: Operatoren: + - * / und ( )
akzeptierte Zahlenformen: 123; 123.123; .123
zwischen einzelnen Operatoren/Operanden kann (muss aber nicht) ein Leerzeichen stehen: 123+321;123 + 321; ( 123+ 321)
Großteil der Anforderungen mussten ja schon in ttp://www.hackerboard.de/thread.php?threadid=31713 erfüllt werden.
Einschränkungen:
Ihr braucht negative Zahlen nicht zu erkennen, diese sollte der Benutzer in Form (0-123) oder 0-123 eingegeben (also als Null minus Zahl) .
Ihr könnte allerding trotzdem eine Erkennung basteln
.
Am einfachsten (imho) wäre es dazu, dem Benutzer die gewünschte Form für negative Zahlen mitzuteilen (z.B immer (-Zahl) und diese Erkennung vor der Umwandlung von Infix nach UPN laufen zu lassen wobei dann alle Vorkommen von (-Zahl) durch (0-Zahl) ersetzt werden.
Teilaufgabe b)
Verbinde dieses Modul mit dem aus "Aus klein mach groß": Teil3 - Rechnen mit Zahlen
Da dieses per Aufgabenstellung einen String entgegen nimmt, sollten dabei keine Probleme auftreten![Wink ;) ;)](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
Funktioniere die Ausgabeoption des UPN moduls so um, dass dem Benutzer auf Wunsch die Zwischenrechnungen des UPN Moduls ausgegeben werden.
Fange die Division durch 0 ab (Programm soll nicht abstürzen/unerwartet terminieren).
Aus diesen "Einzelteilen" ist nun ein Taschenrechner entstanden, der ein bisschen mehr kann, als die Standarddinger aus den Bücheraufgaben
.
Wenn bei der Umsetzung nichts schiefgelaufen ist, so sollten Terme wie (2.8+8 )*(3+7/2.9)-(456.1128*102)/*1337
anstandslos akzeptiert und ausgerechnet werden können.
Optional: man kann auch COS/TAN /MOD /POW hinzufügen. Beim umwandeln von Infix zu UPN kann man z.B COS durch 'C' und TAN durch 'T' ersetzen und UPN Modul erweitern. Man kommt allerdings nicht umhin, ein paar Sonderregel für COS/TAN und weitere unäre (einstellige) Operatoren hinzuzufügen: im UPN Modul darf bei diesen Operatoren nur ein Operand vom Stack geholt werden. Aber das ist wohl doch eine Aufgabe für Fortgeschrittene
.
"Aus klein mach groß": Teil3 - Rechnen mit Zahlen
"Aus klein mach groß": Teil2 - Zahlen und Satzzeichen
sowie
"Aus klein mach groß": Teil1 - Stack
Wie auch vorher richtet es sich primär an Anfänger - deshalb sind die Anforderungen und Grenzen etwas "enger" gesteckt.
Teilaufgabe a)
Infixterm nach Postfix (UPN) umwandeln.
wir alle kennen Infixnotation für "normale" Rechenvorgänge:
1+2+4 oder (2+3)*(6+7)
Infixnotation heißt eigentlich, dass Operatoren(+*-) zwischen den Operanden stehen: 1+2
Hier "Aus klein mach groß": Teil3 - Rechnen mit Zahlen haben wir schon eine andere Notation kennengelernt und auch gesehen, dass das Abarbeiten solcher "Rechenanweisungen" in der UPN Notation programmiertechisch vergleichsweise einfach umgesetzt werden kann. Die Programme aus "Aus klein mach groß": Teil3 - Rechnen mit Zahlen können Benutzereingaben in solcher Form entgegennehmen und ausrechnen. Allerdings ist es für den Benutzer sehr gewöhnungsbedürftig, seine Terme erstmal in diese Form zu bringen - das wollen wir jetzt "übernehmen"
Programmiere also ein Modul, welches "normale" Infixeingaben in UPN Form bringt und als String zurückgibt. Dazu kann man "Aus klein mach groß": Teil2 - Zahlen und Satzzeichen entsprechend erweitern/anpassen.
Jetzt muss man aber dararuf achten, dass alle Zahlen korrekt eingegeben werden - uneindeutige Eingabeformen wie 123.123.132 sollten mit einer Fehlermeldung (am besten mit dem genaueren Stellenhinweis) quittiert werden, da der Benutzer durchaus 123.123+.123 gemeint haben könnte und sich vertippt hat.
Weiterhin muss man die Prioritäten der einzelnen Rechenzeichen beachten: - * / vor + - und () sind "am mächtigsten"
akzeptiert werden sollten: Operatoren: + - * / und ( )
akzeptierte Zahlenformen: 123; 123.123; .123
zwischen einzelnen Operatoren/Operanden kann (muss aber nicht) ein Leerzeichen stehen: 123+321;123 + 321; ( 123+ 321)
Großteil der Anforderungen mussten ja schon in ttp://www.hackerboard.de/thread.php?threadid=31713 erfüllt werden.
Einschränkungen:
Ihr braucht negative Zahlen nicht zu erkennen, diese sollte der Benutzer in Form (0-123) oder 0-123 eingegeben (also als Null minus Zahl) .
Ihr könnte allerding trotzdem eine Erkennung basteln
Am einfachsten (imho) wäre es dazu, dem Benutzer die gewünschte Form für negative Zahlen mitzuteilen (z.B immer (-Zahl) und diese Erkennung vor der Umwandlung von Infix nach UPN laufen zu lassen wobei dann alle Vorkommen von (-Zahl) durch (0-Zahl) ersetzt werden.
Benötigt: OperatorenStack.
gehe einen Term von links nach rechts durch.
- Eine Zahl kann direkt in den Ausgabestring kopiert werden.
- eine '(' wird immer auf dem Stack abgelegt
- wenn eine ')' vorkommt, so werden alle Operatoren solange vom Stack entfernt und in den Ausgabestring kopiert, bis eine ')' vorkommt. Diese wird anschließend aus dem Stack entfernt (ohne in die Ausgabe kopiert zu werden).Ist der Stack leer und eine ')' kam nicht vor, so war die Eingabe fehlerhaft![Wink ;) ;)](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
- 1. ist das aktuelle Zeichen ein Operator, so prüfe den Top-Operator im Stack:
-- Stack leer -> lege den Operator ab
-- Top-Operator im Stack hat höhere oder gleiche Priorität -> pope diesen aus dem Stack in die Ausgabe. Gehe wieder zum schritt 1 (Operatorenvergleich)
-- Top-Operator im Stack ist eine '(' -> lege den aktuellen Operator auf den Stack
-- Top-Operator im Stack hat kleinere Priorität ->lege den aktuellen Operator auf den Stack ab
Ende des Terms erreicht: pope alle Operatoren vom Stack zur Ausgabe, ist eine '(' dabei, so war die Eingabe fehlerhaft![Wink ;) ;)](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
gehe einen Term von links nach rechts durch.
- Eine Zahl kann direkt in den Ausgabestring kopiert werden.
- eine '(' wird immer auf dem Stack abgelegt
- wenn eine ')' vorkommt, so werden alle Operatoren solange vom Stack entfernt und in den Ausgabestring kopiert, bis eine ')' vorkommt. Diese wird anschließend aus dem Stack entfernt (ohne in die Ausgabe kopiert zu werden).Ist der Stack leer und eine ')' kam nicht vor, so war die Eingabe fehlerhaft
- 1. ist das aktuelle Zeichen ein Operator, so prüfe den Top-Operator im Stack:
-- Stack leer -> lege den Operator ab
-- Top-Operator im Stack hat höhere oder gleiche Priorität -> pope diesen aus dem Stack in die Ausgabe. Gehe wieder zum schritt 1 (Operatorenvergleich)
-- Top-Operator im Stack ist eine '(' -> lege den aktuellen Operator auf den Stack
-- Top-Operator im Stack hat kleinere Priorität ->lege den aktuellen Operator auf den Stack ab
Ende des Terms erreicht: pope alle Operatoren vom Stack zur Ausgabe, ist eine '(' dabei, so war die Eingabe fehlerhaft
Verbinde dieses Modul mit dem aus "Aus klein mach groß": Teil3 - Rechnen mit Zahlen
Da dieses per Aufgabenstellung einen String entgegen nimmt, sollten dabei keine Probleme auftreten
Funktioniere die Ausgabeoption des UPN moduls so um, dass dem Benutzer auf Wunsch die Zwischenrechnungen des UPN Moduls ausgegeben werden.
Fange die Division durch 0 ab (Programm soll nicht abstürzen/unerwartet terminieren).
Aus diesen "Einzelteilen" ist nun ein Taschenrechner entstanden, der ein bisschen mehr kann, als die Standarddinger aus den Bücheraufgaben
Wenn bei der Umsetzung nichts schiefgelaufen ist, so sollten Terme wie (2.8+8 )*(3+7/2.9)-(456.1128*102)/*1337
anstandslos akzeptiert und ausgerechnet werden können.
Optional: man kann auch COS/TAN /MOD /POW hinzufügen. Beim umwandeln von Infix zu UPN kann man z.B COS durch 'C' und TAN durch 'T' ersetzen und UPN Modul erweitern. Man kommt allerdings nicht umhin, ein paar Sonderregel für COS/TAN und weitere unäre (einstellige) Operatoren hinzuzufügen: im UPN Modul darf bei diesen Operatoren nur ein Operand vom Stack geholt werden. Aber das ist wohl doch eine Aufgabe für Fortgeschrittene