IT 2 – WS 2008/2009 – Übungsblatt 10 Abzugeben bis 9.1.2009 Beispiel 10.1 [Datum.java, Zeitpunkt.java, Intervall.java, Arbeitszeiten.java] Die Klasse Arbeitszeiten aus dem Projekt Aufgabenverwaltung soll realistischer gestaltet werden, sodass Wochenenden, Feiertage, Urlaube und individuelle Arbeitszeiten eingetragen werden können. Dazu sollen die Arbeitszeiten als Liste von Arbeitsintervallen gespeichert werden. • Implementieren Sie eine Klasse Datum mit dem Konstruktor Datum(int jahr, int monat, int tag). • Fügen Sie in der Klasse Zeitpunkt (Beispiel 5.5) einen Konstruktor Zeitpunkt(Datum tag, int stunde, int minute) hinzu. • Implementieren Sie die Klasse Intervall mit dem Konstruktor Intervall(Zeitpunkt beginn, Zeitpunkt ende) und den Methoden Zeitpunkt getBeginn(), Zeitpunkt getEnde(), die den Beginn und das Ende des Intervalls zurückliefern. • Implementieren Sie die Klasse Arbeitszeiten neu. Es gibt einen Konstruktor Arbeitszeiten(), der ein Objekt der Klasse Arbeitszeiten zurückliefert, in das noch keine Arbeitszeiten eingetragen sind. Mit der Methode boolen addIntervall(Intervall arbeitszeit) kann eine Arbeitszeit eingetragen werden. Diese Methode soll die angegebene arbeitszeit nicht eintragen und false zurückliefern, wenn die angegebene arbeitszeit sich mit bereits eingetragenen Arbeitszeiten überschneidet (sonst true). Die Methode ArrayList<Intervall> getArbeitszeiten(Datum tag) liefert eine Liste der Arbeitsintervalle am angegebenen tag zurück. Hinweis: Beachten Sie, dass das eingetragene Arbeitsintervall über diesen Tag hinausgehen kann. Wurde z.B. das Intervall 1.12.2008/23:00 – 3.12.2008/01:00 eingetragen, soll getArbeitszeiten(2.12.2008) eine Liste mit einem Intervall 2.12.2008/00:00 – 2.12.2008/24:00 zurückliefern. • Implementieren Sie in der Klasse Datum eine statische Methode static boolean isCorrect(int jahr, int monat, int tag), die true zurückliefert, wenn das angegebene Datum korrekt ist, d.h. wenn der angegebene Tag existiert (z.B. nicht der 29.2.2009). Beispiel 10.2 [Josephus.java] Schreiben Sie eine Klasse Josephus, die einen parameterlosen Konstruktor und eine Methode static int getWinner(int n, int m) enthält. Die Methode getWinner() bestimmt den Gewinner eines Auszählreimes: n Personen mit den Nummern 1,…,n stehen im Kreis. Es muss jeweils die m-te Person ausscheiden (der Auszählreim beginnt in der ersten Runde bei Person 1, dann jeweils nach der ausgeschiedenen Person), bis nur mehr eine Person übrig ist – der Gewinner. Die Nummer des Gewinners soll zurückgeliefert werden. D.h. für n=9 und m=5 müssen der Reihe nach die Personen 5 1 7 4 3 6 9 2 ausscheiden, und der Gewinner ist die Nummer 8. Hinweis: Dieses Beispiel kann mit und ohne Rekursion gelöst werden. 1 IT 2 – WS 2008/2009 – Übungsblatt 10 Beispiel 10.3 [Hanoi.java] In dieser Aufgabe soll der Lösungsweg für das Problem der „Türme von Hanoi“ berechnet werden. Dieses Problem besteht aus drei Stäben A, B und C, auf die mehrere gelochte Scheiben gelegt werden können, welche alle unterschiedlich groß sind (siehe Abb. unten). Zu Beginn liegen alle Scheiben auf Stab A, der Größe nach geordnet, mit der größten Scheibe unten und der kleinsten oben. Ziel des Spiels ist es, den kompletten Scheiben-Stapel von A nach C zu versetzen. Bei jedem Zug darf die oberste Scheibe eines beliebigen Stabes auf einen der beiden anderen Stäbe gelegt werden, vorausgesetzt, dort liegt nicht schon eine kleinere Scheibe. Folglich sind zu jedem Zeitpunkt des Spieles die Scheiben auf jedem Stab der Größe nach geordnet. Implementieren Sie die Klasse Hanoi mit der statischen Methode static ArrayList<String> getHanoiSequence(int n), die den Lösungsweg für ein Problem der Größe n (=Anzahl der Scheiben auf Stab A) berechnet und die notwendigen Bewegungen der Scheiben (in der richtigen Reihenfolge) als ArrayList ausgibt. Dabei werden die Bewegungen durch folgende Strings bezeichnet: "AB" … lege die oberste Scheibe von A auf B "AC" … lege die oberste Scheibe von A auf C "BA" … lege die oberste Scheibe von B auf A usw. Stab A Stab B Abb. „Türme von Hanoi“ 2 Stab C IT 2 – WS 2008/2009 – Übungsblatt 10 Beispiel 10.4 [Umkehren.java] SimpleList ist eine Klasse, die eine einfache Liste von Strings beschreibt. Der Zugriff auf eine SimpleList ist nur mit den angegebenen Methoden removeLast() und addFirst() möglich: class SimpleList { /** * Entfernt den letzten String aus der SimpleList * und liefert ihn zurück. Wenn die SimpleList leer * ist, liefert removeLast() null zurück . */ public String removeLast() { … } /** Fügt s als ersten String in die SimpleList ein . */ public void addFirst(String s) { … } } Implementieren Sie eine Klasse Umkehren mit einer Methode static void invert(SimpleList list), die die Reihenfolge der Strings in list umkehrt, also z.B. die Liste mit den Elementen ("a","b","c","d","e") in die Liste mit den Elementen ("e","d","c","b","a") umwandelt. Implementieren Sie zum Testen von Umkehren auch die Klasse SimpleList. Beispiel 10.5 [RekursiveF.java] Implementieren Sie in der Klasse RekursivF eine Methode int f(int m, int n), die folgende Funktion f berechnet: • f(m,n)=0 wenn m<=0 oder n<=0, • f(m,n) = f(m-1,2n) - f(m-1,n) wenn m,n > 0 und n ungerade ist, • f(m,n) = f(m,n/2) + m*n/2 wenn m,n>0 und n gerade ist. Implementieren Sie weiters eine Methode static String[] allPrimes1000(), die ein String-Array zurückgibt, das genau alle Strings "(m,n)" mit 1<=m,n<=1000 enthält, für die f(m, n) eine Primzahl ist, also "(2,3)", "(2,5)", … (in beliebiger Reihenfolge). Beispiel 10.6 [Triple.java] Implementieren Sie die Klasse Triple mit einer Methode static boolean containsTriple(int[] liste), die true zurückliefert, wenn es ein Zahl gibt, die in liste genau dreimal vorkommt. 3