Fachhochschule Regensburg

Werbung
Fachhochschule Regensburg
Algorithmen und Datenstrukturen
Name: ________________________
Aufgabensteller: Prof. Sauer
Vorname: _____________________
April 1999
1. Aufgabe
Schreibe für die in der Vorlesung entwickelte Klassenschablone „Stapel“ eine Anwendung zur
Auswertung voll geklammerter arithmetischer Ausdrücke. Das Ergebnis der Auswertung ist ein
Zahlenwert vom Typ „double“.
Zur Auswertung arithmetischer Ausdrücke beachte und analysiere das folgende Bsp.: (((6 + 9)/3)*(6 –
4)). Durch Einlesen der Zeichen bzw. Zahlen in einen Stapel, der Operations-Zeichen aufnimmt bzw.
in einen Stapel, der Zahlen jeweils bis zur ersten schließenden Klammer aufnimmt, kann die
Auswertung direkt vorgenommen werden:
(((6 + 9)/3)*(6 – 4))
erste schließende rechte Klammer
9
6
zahlen
+
operationen
Abb. 1: Stapel unmittelbar vor Erreichen der ersten rechten Klammer
15
zahlen
operationen
Abb. 2: Stapel unmittelbar nach dem Einlesen der ersten rechten Klammer
Nach der zweiten rechten Klammer liegt folgende Verarbeitung vor:
3
15
zahlen
/
operationen
5
zahlen
operationen
Abb. 3: Stapel unmittelbar nach Erreichen bzw. Verarbeitung der zweiten rechten Klammer
Nach der letzten umschließenden Klammer ergeben sich die folgenden weiteren
Verarbeitungsschritte:
4
6
5
zahlen
*
operationen
6-4 = 2
2
5
zahlen
5*2=10
*
operationen
10
zahlen
operationen
2. Aufgabe
Schreibe ein Programm, das einen arithmetischen Ausdruck in „Infix“-Schreibweise aufnimmt und
einen äquivalenten Ausdruck in „Postfix“-Schreibweise ausgibt. Es sollen generell Zahlen vom Typ
„double“ verarbeitet werden.
Bsp.: Konvertierung des Ausducks 3*X+(Y – 12) – Z in die Postfix-Schreibweise
(a) 3 * X + (Y – 12) - Z
Eingabe
Ausgabe: 3
(b) 3 * X + (Y – 12) - Z
Eingabe
„*“ kommt in den Stapel
Ausgabe: 3
(c) 3 * X + (Y – 12) - Z
Eingabe
Ausgabe: 3X
(d) 3 * X + (Y – 12) - Z
Eingabe
„*“ kommt aus dem Stapel in die Ausgabe, „+“ kommt in den Stapel
Ausgabe: 3X*
(e) 3 * X + (Y – 12) - Z
Eingabe
Die öffnende Klammer kommt in den Stapel: (+
(f) 3 * X + (Y – 12) - Z
Eingabe
Ausgabe: 3X*Y
(g) 3 * X + (Y – 12) - Z
Eingabe
„-„ kommt in den Stapel: -(+
(h) 3 * X + (Y – 12) - Z
Eingabe
Ausgabe: 3X*Y12
(i) 3 * X + (Y – 12) - Z
Eingabe
Alles bis zur linken Klammer wird aus dem Stapel entnommen und kommt in die Ausgabe
Stapel: +
Ausgabe: 3X*Y12(j) 3 * X + (Y – 12) - Z
Eingabe
Alles bis zur linken Klammer wird aus dem Stapel entnommen und kommt in die Ausgabe
Stapel: Ausgabe: 3X*Y12-+
(k) 3 * X + (Y – 12) - Z
Eingabe
Alles bis zur linken Klammer wird aus dem Stapel entnommen und kommt in die Ausgabe
Stapel: Ausgabe: 3X*Y12-+Z
(l) Die noch im Stapel liegenden Operationen werden aus dem Stapel entfernt und in die Ausgabe
gebracht.
Ausgabe: 3X*Y12-+ZDie folgende Beschreibung (in Pseudocode) zeigt, wie der Algorithmus in einem Programmablauf
eingebettet werden kann:
1. Initialisiere einen Stapel zur Speicherung von Zeichen für die Aufnahme von Operationssymbolen
und Klammern.
2. do
if (die nächste Eingabe ist eine linke Klammer)
Lies die linke Klammer und lege sie auf dem Stapel ab.
else if (die nächste Eingabe ist eine Zahl oder ein anderer Operand)
Lies den Operand und schreibe ihn in die Ausgabe.
else if (die nächste Eingabe ist eines der Operations-Symbole)
{ Kellere aus und gib aus, bis drei Dinge auftreten:
(1) Der Stapel ist leer.
(2) Das nächste Symbol auf dem Stapel ist eine linke Klammer
(3) Das nächste Symbol ist eine Operation von geringerem Rang als die vom nachsten
Eingabesymbol
Falls eine dieser Situationen auftritt, beende das Kellern, lies das nächste Eingabesymol
und lege es auf dem Stapel ab
}
else
{ Lies und lege das nächste Eingabe-Symbol ab (,das eine rechte Klammer sein sollte).
Kellere aus und gib die Operation aus aus dem Stapel aus, bis das nächste Symbol
eine linke Klammer ist.
Falls keine linke Klammer gefunden wird, dann gib die Fehlermeldung aus: "Keine
ausgeglichene Anzahl von Klammern“ und halte an.
}
while (es gibt noch etwas zum Einlesen).
3. Kellere aus und gib aus die noch vorhandenen Operationen auf dem Stapel. (Es sollte keine linke
Klammer übrig sein, anderenfalls hatte der Ausdruck der Eingabe nicht eine ausgeglichene Zahl
von Klammern.
Gib das zu diesem Algorithmus zugehörige C++-Programm an. Das Programm soll die
Klassenschablone Stapel aus der verwenden.
3. Aufgabe
Gegeben ist die folgende Beschreibung eines Programmablaufs zur Stapelverarbeitung:
1. Initialisiere einen Stapel zur Aufnahme von Zeichen.
2. do
if (die nächste Eingabe ist eine linke Klammer)
Lies die linke Klammer und lege sie auf dem Stapel ab.
else if (die nächste Eingabe ist eine Zahl oder ein anderer Operand)
Lies den Operand und schreibe ihn in die Ausgabe.
else if (die nächste Eingabe ist eines der Operations-Symbole)
Lies das Operations-Symol und lege es auf dem Stapel ab.
else
{ Lies und lege das nächste Eingabe-Symbol ab (,das eine rechte Klammer sein sollte).
Es sollte dann noch ein Operations-Symbol auf den Stapel geben. Kellere es aus und
schreibe es in die Ausgabe.
Falls es eine solches Symbol nicht gibt, gibt es eine Fehlermeldung: „Zu wenig
Operationen im Infix-Ausdruck“ und halte das Programm an.
Nach dem Auskellern des Operationssymbols, sollte noch eine linke Klammer auf dem
Stapel sein. Kellere sie aus und lege sie ab.
Gibt es keine linke Klammer, gib die Fehlermeldung aus: Keine ausgeglichene Anzahl
von Klammern“ und halte sie an.
}
while (es gibt noch etwas zum Einlesen).
3. Der Stapel sollte jetzt leer sein. Andernfalls gibt es eine Fehlermeldung: „Der Ausdruck war nicht
voll geklammert“.
Ein total geklammerter arithmetischer Ausdruck in Infix-Schreibweise, z.B. (((A+7)*(B/C)-(2*D))
ergibt nach einer in dem vorliegenden Programmablauf beschriebenen Verarbeitung den PostfixAusdruck: A7+BC/*2D*Realisiere diesen Programmablauf für total geklammerte arithmetische Ausdrücke in einem
vollständigen C++-Programm, das die Klassenschablone für einen Stapel benutzt.
Herunterladen