Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme Dr. Werner Struckmann 15. April 2016 Programmieren II 9. Übungsblatt Hinweis: Die Aufgaben dieses Übungsblatts sollten während der Rechnerübungen der dritten Semesterwoche bearbeitet werden. Insgesamt werden in diesem Semester fünf Pflichtaufgaben gestellt. Dieses Übungsblatt enthält noch keine Pflichtaufgabe. Die erste Pflichtaufgabe wird sich auf dem nächsten Übungsblatt befinden. Aufgabe 50: Zahlen der Form 2 35 heißen gemischte Zahlen. Sie lassen sich durch drei Attribute x, y, z ∈ N mit z 6= 0, 0 ≤ y < z und ggT(y, z) = 1 eindeutig charakterisieren. x beschreibt den ganzzahligen Anteil, y den Zähler des Bruchteils und z dessen Nenner. Für das Beispiel gelten x = 2, y = 3 und z = 5. Für die gemischte Zahl 5 ist beispielsweise x = 5, y = 0 und z = 1. 0 wird durch x = 0, y = 0 und z = 1 repräsentiert. Schreiben Sie eine Klasse PositiveGemischteZahl zur Darstellung dieser Zahlen. Sie soll Methoden zur Addition, Subtraktion, Multiplikation und Division sowie zu den Vergleichsoperationen enthalten. Wenn eine größere von einer kleineren Zahl subtrahiert wird, ist das Ergebnis 0. Außerdem soll die Methode String toString() zur Umwandlung von gemischten Zahlen in Zeichenfolgen programmiert werden. Beispielsweise soll 2 53 den String "2.3/5" liefern. Achten Sie darauf, dass gemischte Zahlen stets gekürzt gespeichert werden. Testen Sie Ihre Klasse an geeigneten Beispielen. Zur Behandlung negativer gemischter Zahlen soll die Klasse PositiveGemischteZahl zur Klasse GemischteZahl abgeleitet werden. Führen Sie hierzu in der Unterklasse ein boolesches Attribut positiv ein und überlagern Sie die Methoden für die arithmetischen und Vergleichsoperationen sowie die Methode String toString(). Beispielsweise gelten 17 52 und 2 16 /(−7 87 ) = − 189 . 2 61 − 7 78 = −5 24 Berechnen Sie mit Ihrem Programm den genauen Wert der Summe 40 X (−1)i+1 i=1 i =1− 1 1 1 1 1 1 + − + − + ... − 2 3 4 5 6 40 und vergleichen Sie ihn mit ln(2). Empfehlung: Testen Sie die Ihre Methoden mithilfe des JUnit-Pakets. Aufgabe 51: werden. In dieser Aufgabe soll der Umgang mit Programmen des JDKs geübt a) Übersetzen Sie Ihre Lösung von Aufgabe 50 mit den entsprechenden Optionen, so dass der Debugger jdb verwendet werden kann. Führen Sie anschließend Ihr Programm mit dem Debugger schrittweise aus und sehen Sie sich die Objekte nach den Schritten an. b) Erstellen Sie ein jar-Archiv, das die erforderlichen Dateien enthält und starten Sie das Programm aus dem Archiv heraus. c) Kommentieren Sie die Elemente Ihres Programms mit den in der Übung vorgestellten Tags. Erzeugen Sie dann mit javadoc eine HTML-Seite und sehen Sie sich die Seite mit einem Browser an. Zusatz: Gegeben sei die folgende Java-Methode bubblesort, die das Parameterfeld sortieren soll. Die Methode enthält einen Fehler. Finden Sie den Fehler, indem Sie das Programm schrittweise mit dem Debugger jdb ausführen. static void bubblesort(int[] a) { int n=a.length; for (int i=0; i<n-1; i++) for (int j=n; j>i; j--) if (a[j-1]>a[j]) { int t=a[j]; a[j]=a[j-1]; a[j-1]=t; } } Aufgabe 52: Widerstände sind elektrische Bauteile mit einem Widerstandswert, der in Ohm (Ω) gemessen wird. Aus Widerständen lassen sich Netze gemäß der folgenden Regeln bilden: – Ein einzelner Widerstand ist ein Netz. – Zwei Netze mit den Widerständen R1 und R2 können in Serie geschaltet werden. Der Gesamtwiderstand beträgt R = R1 + R2 . – Zwei Netze mit den Widerständen R1 und R2 können parallel geschaltet werden. Der Gesamtwiderstand R ist durch R1 = R11 + R12 gegeben. Bearbeiten Sie die folgenden Aufgaben. a) Definieren Sie eine abstrakte Klasse Net mit der Methode abstract double ohm(). b) Leiten Sie von Net eine konkrete Klasse Resistor für Widerstände ab. Der Widerstandswert ist unveränderlich. c) Definieren Sie zwei Klassen Serial und Parallel für die serielle und die parallele Schaltung von Netzen. Die Konstruktoren dieser Klassen erhalten je zwei Netze als Argumente. –2– d) Schreiben Sie eine Anwendung, die das Netz R1 R2 R3 R4 R5 R6 aufbaut und den Gesamtwiderstand ausgibt. Die Widerstände R1 , R2 , . . . , R6 besitzen die Werte 100 Ω, 200 Ω, . . . , 600 Ω. e) Die Basisklasse Net wird erweitert um die Definition abstract int resistors(); // liefert die Anzahl der Widerstände Passen Sie Ihre Klassen an. Für das angegebene Netz soll die Methode den Wert 6 liefern. f) Als neue Sorte von Widerständen werden „Potentiometer“ eingeführt. Potentiometer sind Bauteile mit einem regelbarem Widerstandswert. Leiten Sie von Net eine Klasse Potentiometer ab, die zusätzlich eine Set-Methode setOhm für den Widerstandswert enthält. g) Ersetzen Sie in der obigen Schaltung R4 durch ein Potentiometer. Schreiben Sie eine weitere Anwendung, die eine Liste der Widerstandswerte ausgibt, wenn das Potentiometer von 0 Ω bis 5 kΩ in Schritten von 200 Ω hochgeregelt wird. Aufgabe 53: Insertionsort (Sortieren durch Einfügen) ist ein elementarer Sortieralgorithmus. Er ist sehr gut zum Sortieren kleiner Datenmengen geeignet. Algorithmus: Am Anfang und nach jedem Schritt des Verfahrens besteht die zu sortierende Folge a0 , . . . , an−1 aus zwei Teilen: Der erste Teil a0 , . . . , aj−1 ist bereits aufsteigend sortiert, der zweite Teil aj , . . . , an−1 ist noch unsortiert. Das Element aj wird als nächstes in den bereits sortierten Teil eingefügt, indem es der Reihe nach mit aj−1 , aj−2 usw. verglichen wird. Sobald ein Element ai mit ai ≤ aj gefunden wird, wird aj hinter ai eingefügt. Wird kein solches Element gefunden, wird aj an den Anfang der Folge gesetzt. Damit ist der sortierte Teil um ein Element länger geworden. Im nächsten Schritt wird aj+1 in den sortierten Teil eingefügt usw. Am Anfang besteht der sortierte Teil nur aus dem Element a0 , zum Schluss aus allen Elementen a0 , . . . , an−1 . a) Formulieren Sie den Algorithmus Insertionsort als Java-Methode. b) Berechnen Sie die Best- und die Worst-Case-Komplexität Ihrer Methode. –3– c) Beweisen Sie die partielle und die totale Korrektheit Ihrer Methode. d) Testen Sie Ihre Methode, indem Sie mithilfe der Klasse java.util.Random zufällige Felder generieren und diese anschließend sortieren. Überprüfen Sie die Korrektheit Ihrer Methode durch geeignete assert-Anweisungen. Aufgabe 54: Eine physikalische Größe besteht aus einer Anzahl und einer Einheit, beispielsweise „2,34 Meter“. Definieren Sie einen Aufzählungstyp Length, dessen Elemente verschiedene Längeneinheiten repräsentieren, wie zum Beispiel die folgenden: Einheit Meter Fuß Kilometer Meile Lichtjahr Angström Meter pro Einheit 1 0,3048 1000 1632,9 9,461 · 1015 10−10 Abkürzung m ft km mi LY Å Schreiben Sie außerdem eine Klasse Distance, die eine Entfernung durch eine Anzahl und eine Einheit repräsentiert. Die Klasse soll mindestens die folgenden Methoden enthalten: Distance Konstruktor aus Anzahl und Einheit. Negative Zahlen werden durch den Betrag ersetzt. count Liefert die Anzahl der Einheiten dieser Entfernung. unit Liefert die Einheit dieser Entfernung als Element des Aufzählungstyps Length. add Liefert die Summe aus der aktuellen Entfernung und einer anderen Entfernung als neues Objekt. Das Ergebnis hat die gleiche Einheit wie die aktuelle Entfernung. toString Liefert eine Textdarstellung der aktuellen Entfernung. as Liefert die aktuelle Entfernung in einer anderen Einheit. Das folgende Programmfragment addiert zwei Kilometer und eine Meile und gibt das Ergebnis in Kilometer und in Meilen aus. Distance d1 = new Distance(2, Length.km); Distance d2 = new Distance(1, Length.mi); Distance d12 = d1.add(d2); Distance d21 = d2.add(d1); System.out.println(d12); System.out.println(d21); –4–