Lösung

Werbung
Technische Informatik für Ingenieure – WS 2010/2011
Musterlösung Übungsblatt Nr. 3
25. Oktober 2010
Übungsgruppenleiter:
Matthias Fischer
Mouns Almarrani
Rafał Dorociak
Michael Feldmann
Thomas Gewering
Benjamin Koch
Dominik Lüke
Alexander Teetz
Simon Titz
Simon Oberthür
Seite 1(8)
Aufgabe 1:
(Simulation)
Ziel dieser Aufgabe ist es herauszufinden, was das bereitgestellte Programm
„WhatDoIDo.java“ macht.
a) Laden Sie sich die Datei „WhatDoIDo.java“ von der Veranstaltungsseite
(http://wwwhni.uni-paderborn.de/alg/lehre/ws-20102011/tifi/) und kopieren Sie
diese in Ihr TIFI-Projekt in Eclipse.
b) Führen Sie das Programm aus (Rechte Maustaste auf die Datei
„WhatDoIDo.java“ → Run as → Java Application) und verwenden Sie das in
der Vorlesung vorgestellte Verfahren „Simulation eines Computerprogrammes
von Hand“ (siehe Kapitel 2.1 und Ergänzung 2.1).
Tipp: In der Regel reicht eine einzelne Simulation nicht aus.
Lösung:
In den meisten Fällen, wie auch diesem, läßt sich der Algorithmus nicht nur mit einem
Durchlauf des Programms bzw. mit nur einem (Paar von) Eingabewert(en)
bestimmen.Deshalb führt man mehrere Simulationen mit unterschiedlichen Eingaben
aus. Bei mehreren Eingabevariablen ist es allerdings sinnvoll zunächst nur eine Variable
zu ändern, um die Änderungen besser beurteilen zu können.
In den folgenden 4 Simulationen wurde a gleich 5 und b von 1 bis 4 verwendet:
a
b
c
a
b
c
a
b
c
a
b
c
5
1
0
5
2
0
5
3
0
5
4
0
4
0
5
4
1
5
4
2
5
4
3
5
3
0
9
3
1
9
3
2
9
2
0
12
2
1
12
1
0
14
5=5
5+4 = 9
5+4+3 = 12
5+4+3+2 = 14
Technische Informatik für Ingenieure
Seite 2(8)
Die Werte von a und b in der letzten Zeile wurden jeweils ausgegraut, da sie nicht mehr
zum Ergebnis beitragen.
Es ist zu beobachten, dass sich das Ergebnis aus a + (a-1) + (a-2) + … + (a-b+1)
zusammensetzt.
Analog zur Berechnung der Gaußschen Summenformel (siehe Wikipedia) läßt sich dies
vereinfachen zu:

f a ,b=b∗ a−
b−1
2

Alternativ sind folgend vier Simulationen mit a=2 und b von 2 bis 5 dargestellt, bei
denen auch negative Zahlen zum Ergebnis addiert werden:
a
b
c
a
b
c
a
b
c
a
b
c
2
2
0
2
3
0
2
4
0
2
5
0
1
1
2
1
2
2
1
3
2
1
4
2
0
0
3
0
1
3
0
2
3
0
3
3
-1
0
0
-1
1
3
-1
2
3
-2
0
2
-2
1
2
-3
0
0
2+1=3
Aufgabe 2:
2+1+0=3
2+1+0+(-1)=2
2+1+0+(-1)+(-2)=0
(Debugging)
Ein Automatenhersteller entwickelt einen neuen Parkautomaten für Parkhäuser. Bevor
ein Parkender das Parkhaus verlässt, berechnet der Automat den zu zahlenden Betrag.
Nachdem der Parkende mindestens den zu zahlenden Betrag eingeworfen hat, soll der
Automat – wenn nötig – Wechselgeld in 5-, 2- und 1-Cent-Stücken zurückgeben.
So lange die Differenz aus gegebenem und zu zahlendem Geldbetrag mindestens 1
beträgt, soll Geld zurückgegeben werden. Dabei soll die Gesamtzahl der
zurückgegebenen Münzen minimiert werden, indem immer die vom Betrag her
größtmöglichen Münzen zurückgegeben werden.
Ein Entwickler hat das Programm für die Wechselgeldberechnung bereits
implementiert. Allerdings ist sein Programm noch fehlerhaft. Finden Sie mit Hilfe der
Entwicklungsumgebung Eclipse die Fehler im Programm und beseitigen Sie diese.
a) Laden Sie sich die Datei „Wechselgeld.java“ von der Veranstaltungsseite
(http://wwwhni.uni-paderborn.de/alg/lehre/ws-20102011/tifi/) und kopieren
Sie diese in Ihr TIFI-Projekt in Eclipse. Öffnen Sie die Datei durch
Doppelklicken im Package-Explorer und machen Sie sich mit der
Programmstruktur vertraut.
Technische Informatik für Ingenieure
Seite 3(8)
b) Führen Sie das Programm aus (Rechte Maustaste auf die Datei oder im Editor
→ Run as → Java Application) und beobachten Sie was passiert. In dem Fall,
dass das Programm nicht terminiert (z.B. wegen einer „Endlosschleife“),
beenden Sie das Programm durch Drücken des Terminate-Buttons
:
c) Um die Fehler im Programm zu finden, betrachten Sie den Ablauf des
Programms in der Debug-Perspektive von Eclipse und nutzen Sie den
Debugger.
Ein Debugger ist ein Werkzeug, mit dem der Ablauf eines Programms verfolgt werden
kann. Es können Haltepunkte (engl.: Breakpoints) definiert werden, an denen der
Programmablauf angehalten wird und die aktuellen Variablenwerte überprüft werden
können.
Ausgehend von einem Breakpoint kann der Programmablauf schrittweise verfolgt
werden. Setzen Sie als Erstes einen Breakpoint (es können auch mehrere Breakpoints
erstellt werden) in der Zeile 14:
int rueckGeldBetrag = zuZahlen – gegeben;
Dazu doppelklicken Sie in den grauen Bereich links neben der Zeile mit der linken
Maustaste (durch einen weiteren Doppelklick kann der Breakpoint wieder entfernt
werden). Nach dem Doppelklick ist ein blauer Kreis (der Breakpoint) zu sehen:
Starten Sie nun das Programm „Wechselgeld“ im Debug-Modus: Rechte
Maustaste auf „Wechselgeld.java“ im Package-Explorer oder im Editor →
Debug As → Java Application:
Technische Informatik für Ingenieure
Seite 4(8)
Geben Sie nun 33 Cent als zu zahlenden und 51 Cent als gegebenen Betrag ein.
Daraufhin erscheint der folgende Dialog, in dem Sie das Häckchen vor
„Remember by decision“ setzen und mit „Yes“ bestätigen:
Es öffnet sich nun die Debug-Perspektive von Eclipse (Alternativ kann die
Debug-Perspektive auch über: Window → Open Perspective → Other... →
Debug geöffnet werden):
Das Programm wurde bis zu der im Editor farblich hervorgehobenen Zeile
ausgeführt. Alle Zeilen davor wurden bereits ausgeführt und haben eventuell
Variablenwerte gesetzt, die im rechten oberen Fenster „Variables“ angeschaut
Technische Informatik für Ingenieure
Seite 5(8)
(und verändert) werden können. Dort sind auch die eingegebenen Werte 33 und
51 zu sehen.
Mit den „Debug“- und „Java“-Buttons rechts oben kann zwischen der normalen
Java-Perspektive und der Debug-Perspektive gewechselt werden.
Um das Programm weiter auszuführen, gibt es im linken oberen Fenster
„Debug“ drei für uns wichtige Buttons:
- Führt das Programm beginnend bei der aktuell hervorgehobenen Zeile
solange aus, bis ein Breakpoint erreicht wird oder es beendet ist.
- Beendet/Terminiert das Programm.
- Führt die aktuell hervorgehobene Zeile aus.
Führen Sie nun das Programm schrittweise durch Drücken des
-Buttons oder
der F6-Taste weiter aus und beobachten Sie die Varablenwerte im rechten
oberen Fenster „Variables“. Versuchen Sie anhand des Programmverhaltens und
der Änderungen an den Variablenwerten Fehler im Programm zu finden.
d) Passen Sie nun das Programm so an, dass es sich wie erwünscht verhält (siehe
Beschreibung am Anfang der Aufgabe 2). Überprüfen Sie das Verhalten des
Programms mit verschiedenen Eingaben und dem Debugger.
Bei der Eingabe, 33 Cent zu zahlen und 51 Cent gegeben, soll das Programm
Folgendes ausgeben:
Bitte geben Sie den zu zahlenden Betrag in Cent ein:33
Bitte geben Sie den gegebenen Geldbetrag in Cent ein:51
5 zurueck
5 zurueck
5 zurueck
2 zurueck
1 zurueck
Hinweis: Wenn Sie den Quellcode des Programms ändern und speichern, bevor
Sie das Programm beendet haben, erscheint evtl. der folgende Dialog:
Technische Informatik für Ingenieure
Seite 6(8)
Starten Sie in diesem Fall durch Klicken auf den Button „Restart“ das Programm
direkt neu oder beenden Sie es mit dem Button „Terminate“.
Lösung:
public class Wechselgeld {
public static void main(String[] args) {
// Geldbetraege einlesen
Out.print("Bitte geben Sie den zu zahlenden Betrag in Cent ein:");
int zuZahlen = In.readInt();
Out.print("Bitte geben Sie den gegebenen Geldbetrag in Cent ein:");
int gegeben = In.readInt();
// Differenz, die zurueckgegeben werden muss, berechnen
int rueckGeldBetrag = zuZahlen – gegeben;
// rueckGeldBetrag = -18
int rueckGeldBetrag = gegeben – zuZahlen;
// rueckGeldBetrag = 18
Falsch
Richtig
// Ausgabe bei zu wenig gegebenem Geld oder passendem Betrag (kein Rueckgeld)
if (rueckGeldBetrag < 0)
{
Out.println("Sie haben zu wenig Geld gegeben," +
" es fehlen noch " + (-rueckGeldBetrag) + " Cent!");
}
else if (rueckGeldBetrag == 0)
{
Out.println("Kein Rueckgeld.");
}
/*
* Solange Geld zurueckgeben, bis die Differenz zwischen
* dem zu zahlenden Betrag und dem gegebenen Betrag 0 ergibt.
*/
while (zuZahlen > 0)
// Endlosschleife, da zuZahlen immer größer 0
while (rueckGeldBetrag > 0) // Schleife bis rueckGeldBetrag gleich 0
{
if (rueckGeldBetrag >= 5)
{
rueckGeldBetrag = rueckGeldBetrag - 5;
Out.println("5 zurueck");
}
else if (rueckGeldBetrag >= 2)
{
zuZahlen = rueckGeldBetrag – 2;
// zuZahlen wird verändert: Falsch
rueckGeldBetrag = rueckGeldBetrag – 2; // rueckGeldBetrag verringert um 2
Out.println("2 zurueck");
}
else
{
rueckGeldBetrag = rueckGeldBetrag - 1;
Out.println("1 zurueck");
}
}
}
}
Technische Informatik für Ingenieure
Seite 7(8)
Aufgabe 3:
(BNF, Syntaxbäume)
Auf dem zweiten Übungsblatt haben Sie für die folgenden Ausdrücke korrekte
Syntaxbäume angegeben:
e.) ( a * b + (-2))
g.) (a + b / c) - 2 * (3 / b)
1. Geben Sie so wie in der Vorlesung (Kapitel 2.2, Folien 44, 45) für den Ausdruck
e) einen falschen Syntaxbaum an, der die dieselben Operatoren und Variablen
verwendet. Dieser Syntaxbaum wertet den Ausdruck jedoch in der falschen
Reihenfolge aus und führt damit so wie in der Vorlesung zu einem anderen
mathematischen Ergebnis.
2. Für den Ausdruck g) geben Sie einen Syntaxbaum an, der den Ausdruck auch in
einer anderen Reihenfolge auswertet als der Syntaxbaum, den Sie für g) auf
Blatt 2 angegeben haben. Die Ausdrücke der Syntaxbäume sollen jedoch
mathematisch äquivalent bleiben.
Lösung:
e) ( a * b + (-2))
+
-
*
a
b
2
Der folgende Syntaxbaum stellt diesen Ausdruck dar:
a*(b + (-2)).
*
Obwohl im Ausdruck wie auch im Baum dieselben
Operatoren und Variablen benutzt werden und die
Reihenfolge von Operatoren und Variablen in beiden
Ausdrücken identisch ist, entsteht ein anderer
mathematischer Ausdruck.
a
+
-
b
Die unterschiedliche Klammerung drückt sich im Baum
durch die Anordnung der Operatoren im Baum aus: im
Baum niedrig stehende Operatoren werden zuerst ausgewertet.
g.) (a + b / c) - 2 * (3 / b)
2
*
+
b
/
2
/
a
c
3
b
Technische Informatik für Ingenieure
Seite 8(8)
Der folgende Syntaxbaum stellt diesen Ausdruck dar: (a+b/c) – (2*3)/b
In diesem Fall sind die Ausdrücke zwar mathematisch äquivalent, es handelt sich jedoch
um unterschiedliche Ausdrücke. Dies kann bei der Berechnung durch ein
Computerprogramm auch zu unterschiedlichen Ergebnissen führen, da die Reihenfolge
der Auswertung unterschiedlich ist: Falls mit Fließkomma-Arithmetik gearbeitet wird
(Approximation der reellen Zahlen), sind die Ergebnisse durch Rundungsfehler
fehlerbehaftet. Bei unterschiedlicher Reihenfolge der Auswertung kann es zu
unterschiedlichen Rundungsfehlern kommen und damit zu unterschiedlichen
Ergebnissen zweier mathematisch äquivalenten Ausdrücke.
-
/
+
b
b
*
/
a
c
2
3
Zugehörige Unterlagen
Herunterladen