»Programmieren«, WS 2006/2007 Nino Simunic M.A. Nino Simunic ([email protected]) Übungsblatt 5 Aufgabe 1 ZUFÄLLIGES ENGLISCH Der folgende Quelltext zeigt Ihnen, wie man Zufallszahlen erzeugen kann. Dazu benötigt wird zunächst der Import der JavaKlasse Random. Dies wird wie in Zeile 1 des nachstehenden Quelltexts angegeben durchgeführt. (Sie benötigen keine weitere Datei dazu, Random ist Teil des JDK). Um Zufallszahlen zu erzeugen, müssen Sie wie in Zeile 4 ein Random-Objekt erzeugen, um die entsprechenden Zufallszahlerzeugenden Methoden aufrufen zu können: In diesem Fall kümmern wir uns nur um die Methode nextInt(). Durch Aufruf dieser Methode mit einer Ganzzahl können wir uns eine Zufallszahl generieren lassen, die zwischen (inklusive) 0 und dem übergebenen Ganzzahl-Argument liegt. M.a.W., wenn nextInt() mit dem Argument 100 aufgerufen wird (nextInt(100)), so wird eine Zufallszahl zwischen 0 und 100 erzeugt. Führen Sie zum besseren Verständnis das Programm nun ein paar mal aus, und ändern Sie die übergebenen Argumente der nextInt()-Methode. Auch hier kann ein Blick in die Java-API Dokumentation sicherlich hilfreich sein. 1 2 3 4 5 6 7 8 9 10 11 12 14 RandomTest.java import java.util.Random; public class RandomTest { public static void main ( String[] args ) { Random rand = new Random(); int random1 = rand.nextInt(10) ; int random2 = rand.nextInt(100) ; System.out.print( random1); System.out.println( "\t"+random2 ); } } http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/RandomTest.java Ihre Aufgabe besteht nun darin, eine Klasse SentenceGen zu schreiben, welche zufällige englische Sätze ausgibt, und zwar immer nach dem Muster Artikel-Adjektiv-Substantiv-Verb-Artikel-Adjektiv-Substantiv, also bswp. »the big dog chases some happy cat«, oder »some angry girl wants a small boy«, etc. Legen Sie dazu zunächst vier Arrays vom Typ String als Klassenvariablen an, um (mindestens) die folgenden Artikel, Adjektive, Verben, und Substantive verwalten zu können: • • • • Programmieren Nino Simunic M.A. Artikel: Adjektive: Substantive: Verben: a,the,some big,small,angry,happy,green dog,cat,girl,boy eats,chases,loves,wants,sees,betrays Seite 1 Der Zugriff auf Elemente eines Arrays geschieht über den Index, d.h. eine Ganzzahl. Eine solche zu erzeugen sollte Ihnen anhand der Angaben dieses Übungsblatt nicht mehr schwer fallen, so dass Sie zufällig auf Elemente der Arrays zugreifen können. Beachten Sie, dass die Arrays verschiedene Längen besitzen, also das übergeben int-Argumente zur Erzeugung einer Zufallszahl entsprechend variieren muss. Bitte implementieren Sie das Generieren eines Zufallssatzes in einer eigenen Methode generateSentence(), welche als Argument die Anzahl der zu erzeugenden Sätze festhält. Die Rückgabe der Methode soll ein Array vom Typ String sein, welcher die generierten Sätze als Zeichenketten enthält. An generateSentence()-aufrufender Stelle weisen Sie bitte das zurückgegebene Array einer entsprechenden Variable zu, und nutzen diese entsprechend, um über alle generierten Sätze zu iterieren. Wie schon implizit angedeutet, sorgen Sie bitte dafür, dass die Funktionalität von SentenceGen ohne Erzeugung eines SentenceGen-Objekts gewährleistet ist. Es soll also möglich sein, ohne SentenceGen-Objekt in einer main()-Methode (auch aus einer anderen Klasse heraus) Sätze zu produzieren. Zuguterletzt iterieren Sie über die zurückgegebenen Sätze und geben Sie sie aus. Für jetzt achten Sie bei Verwendung mehrerer interagierender Klassen darauf, dass sich alle in einem Verzeichnis befinden. Programmieren Nino Simunic M.A. Seite 2 Aufgabe 2 STUDENT REPOSITORY In dieser Aufgabe sollen sie eine simple Verwaltung für Studenten programmieren. Dazu soll es natürlich möglich sein, Objekte vom Typ Student zu erzeugen (s.u.). Die Verwaltung ist ebenfalls als Klasse (StudentRepository) zu implementieren und soll, wie der Name vermuten lässt, eine (fast) beliebige Zahl Studenten(-Objekte) in einer geeigneten Datenstruktur (Array) verwalten: Studenten sollen hinzugefügt, entfernt, und angesehen werden können. Nähere Informationen zur Modellierung und Implementierung folgen. Ein Student beschreibt sich wie folgt (geklammerte Angaben sind die zu verwendenden Bezeichner) und soll einen oder mehrere Konstruktoren zur Initialisierung der Werte besitzen: • • • Name (name) Matrikelnummer (id) Geburtstag (bday) Die Verwaltung ( StudentRepository ) soll folgende Merkmale besitzen (die entsprechenden Typen, Parameter, und etwaige Rückgabewerte und deren Typen müssen Sie selbst adäquat bestimmen): 1. Verwaltung einer beliebigen Anzahl Studenten in einem Array: repository 2. Die Anzahl der (zu erwartenden) Studenten wird beim Erzeugen des Repositories übergeben und im Konstruktor dann als Längenangabe für repository verwendet Studenten können hinzugefügt werden: addStudent( ) Es wird immer am Ende eingefügt, d.h. nach dem zuletzt eingefügten Studenten – es dürfen also keine nicht-initialisierten Stellen »zwischen Studenten« im Array entstehen Es dürfen keine Dubletten vorhanden sein. D.h., keine Studenten mit identischer id sind gestattet. Beim Hinzufügen eines Studenten dürfen nur "leere“ Positionen verwendet werden –es darf also kein existierender Student überschrieben werden. Falls ein Student mit identischer id vorliegt, soll eine Fehlermeldung ausgegeben werden: [Error: ID exists] Student XYZ mit id 123 konnte nicht hinzugefügt werden Fehlermeldung, wenn das repository voll ist: [Error: Repository full] Student XYZ (123) kann nicht hinzugefügt werden 3. Studenten können unter Angabe der Matrikelnummer abgefragt werden: getStudent( ) 4. Fehlermeldung, wenn nichts gefunden wurde: [Error: ID not found] Student XYZ (123) kann nicht gefunden werden Das Repository soll tabellarisch ausgegeben werden können: printRepository( ) Verwenden Sie zur Strukturierung \t Hinweis: Wenn ein Element im Array nicht initialisiert ist, d.h. null ist, jedoch trotzdem auf Methoden dieses Elements versucht wird zuzugreifen, führt dies zu einer NullPointerException, und ohne weitere Einwirkung auch zum Absturz des Programms. In Ihrem Programm kann genau das vorkommen, wenn das Array noch nicht voll belegt ist: Wenn Sie nun bspw. mit der printRepository-Methode auf alle Elemente und ihre Eigenschaften zugreifen, führt dies bei leeren Stelle zu besagtem Problem: Es gibt keinen Studenten, und somit auch keine id Absturz. Sie sollten folglich an den nötigen Stellen in den Methoden vorher abfragen, ob dort überhaupt ein Objekt vorhanden ist, also das Element ungleich null ist. Testen Sie nicht, ob Attribute eines Objekts == null ist! (Ohne Objekt auch kein Zugriff auf Attribut Absturz). Programmieren Nino Simunic M.A. Seite 3 Tipp: Für addStudent()ist es sinnvoll, getStudent( ) an geeigneter Stelle zu verwenden, um Dubletten aufzuspüren. getStudent() muss im Idealfall so angepasst werden, dass ein boolescher Wert zurückgegeben wird1, um diesen letztendlich in addStudent() in einer Kontrollstruktur zur Überprüfung auf eine vorhandene id zu verwenden: if ( getStudent(1234) ) { // Doublette gefunden } Aufgabe 3 1 2 3 4 5 6 7 8 9 10 11 12 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 BUBBLESORT BubbleSort.java public class BubbleSortTest { public static void main( String[] args ){ int[] numbers = new int[5]; numbers[0] = 5678 ; numbers[1] = 12 ; numbers[2] = 342 ; for ( int i=0; i<numbers.length; i++ ) { for ( int j=0; j<numbers.length-1; j++ ) { if (numbers[j+1]!=0 && numbers[j]!=0){ // if 1 if ( numbers[j] <numbers[j+1] ) { // if 2 int temp = numbers[j+1]; numbers[j+1] = numbers[j]; numbers[j] = temp; } // if2 Ende }// if 1 Ende } // for j Ende } // for i Ende for ( int i=0; i<numbers.length; i++ ){ if ( numbers[i]!=0){ System.out.println(numbers[i]); } } } } http://cl.informatik.uni-duisburg.de/simunic/prog0607/Aufgaben/Code/BubbleSort.java Der Quelltext oberhalb ist die Umsetzung des Bubblesort-Algorithmus zur Sortierung von Werten in einem Array. Das Prinzip (absteigende Sortierung): 1 D.h., wenn kein Student gefunden wird, soll false zurückgeben werden. Programmieren Nino Simunic M.A. Seite 4 Das Array wird von Beginn an durchlaufen. Eine innere Schleife sorgt dafür, dass je zwei nebeneinander stehende Elemente verglichen werden. Ist das mit dem höheren Index größer als das mit dem kleineren Index, so werden die Elemente vertauscht. Nach dem ersten Durchlauf befindet sich das größte Element am niedrigsten Index. Im nächsten Durchlauf muss nur noch bis zum vorletzten Element gelaufen werden, usw. Äußere Schleife benötigt so viele Durchläufe (abnehmender Länge), wie das Array Elemente hat. Die Kontrollstrukturen in Zeile 14 und 25 sind hier nicht zwingend erforderlich. Sie filtern nur Nullen (0) heraus. Wenn es sich jedoch um nicht-primitive Typen handelt, über die iteriert wird, sollten Sie vorsichtshalber diese Kontrollstrukturen beibehalten. Allerdings müssen die Bedingungen dann so formuliert werden, dass die Objekte auf null überprüft werden. Zum besseren Verständnis der Funktionsweise ein weiterer Erklärungsansatz: Der Algorithmus vergleicht der Reihe nach zwei benachbarte Elemente und vertauscht sie, falls sie in der falschen Reihenfolge vorliegen. Dieser Vorgang wird solange wiederholt, bis keine Vertauschungen mehr nötig sind. Hierzu sind in der Regel mehrere Durchläufe erforderlich. Je nachdem, ob auf- oder absteigend sortiert wird, steigen die größeren oder kleineren Elemente wie Blasen im Wasser (daher der Name) immer weiter nach oben, d.h. an das Ende der Reihe. Auch werden immer zwei Zahlen miteinander in "Bubbles" vertauscht. [ http://de.wikipedia.org/wiki/Bubblesort ] • Verständnis: Lesen Sie sich auch den wikipedia-Artikel zu Bubblesort durch. Es ist dort auch ein Quelltext in Java vorhanden. Versuchen Sie zu begreifen, was genau hier passiert. • Schreiben Sie eine Methode, welche die drei Anweisungen aus 16 bis einschließlich 18 enthält. Ein Aufruf dieser Methode soll die Zeilen 14 -18 ersetzen. • Implementieren Sie eine Methode sortByID in Ihrer StudentRepository, welche das Bubblesort-Verfahren nutzt und Studenten nach id sortiert. Wenn Sie mit Aufgabe 2 nicht fertig geworden sind, programmieren Sie eine simple Student-Klasse wie in der Vorlesung gezeigt. Selbiges gilt für die nächste Aufgabe. • Schreiben Sie eine Methode sortByYear, welche das Bubblesort-Verfahren nutzt: Sortieren Sie also nach Geburtsdatum. Denken Sie daran: Instanz- oder Klassenvariablen können auch komplexe Typen sein. • Was muss man ändern, um eine aufsteigende Reihenfolge durch die Sortierung zu erhalten? Heiter weiter, und gutes Gelingen! Programmieren Nino Simunic M.A. Seite 5