Prof. r. V. Linnemann Lübeck, den. Oktober 00 Universität zu Lübeck Institut für Informationssysteme lgorithmen und atenstrukturen Sommersemester 00. Klausur Lösungen Hinweis: chten Sie bei Programmieraufgaben darauf, Ihre Lösungen zu kommentieren, so dass es möglich ist, den Lösungsweg zu verfolgen und die Idee der gewählten Implementierung zu verstehen. ehlende Kommentare führen zu einem erheblichen Punktabzug Insgesamt sind bei dieser Klausur 0 Punkte zu erzielen. Zum estehen der Klausur genügen 0% der Punkte Lösung : Laufzeitstack Was bewirkt die wasmachich - Methode der folgenden Klasse? Was bewirkt die main - Methode? Zeichnen Sie den Laufzeitstack jeweils zu nde eines wasmachich - ufrufs, nachdem der rgebniswert im Stack vermerkt wurde. Verwenden Sie als Rückkehradresse jeweils den in der Klasse angegebenen Kommentar. public class WasMachIch { public static int wasmachich(string, char, int i){ if (i>=.length()) return 0; if (.chart(i)==) return wasmachich(,, i+) /* */ +; else return wasmachich(,, i+) /* */; public static void main (String[] args){ int ergebnis = wasmachich("",,0) /* C */; System.out.println(ergebnis); ( Punkte) /
Lösung: wasmachich liefert als int - Wert, wie oft das Zeichen in der Zeichenkette ab der Position mit dem Index i vorkommt, d.h. bei i = 0 (. ufruf) wird abgeliefert, wie oft das Zeichen in der Zeichenkette vorkommt. ie main - Methode gibt über die Konsole aus, wie häufig der uchstabe in der Zeichenkette O vorkommt, d.h. es wird die Zahl ausgegeben Laufzeitstack: rgebnis - i 0 Rückkehradresse C rgebnis - i Rückkehradresse rgebnis - i Rückkehradresse rgebnis - i Rückkehradresse rgebnis 0 i 4 Rückkehradresse rgebnis - i 0 Rückkehradresse C rgebnis - i Rückkehradresse rgebnis - i Rückkehradresse rgebnis i Rückkehradresse rgebnis - i 0 Rückkehradresse C rgebnis i Rückkehradresse rgebnis - i 0 Rückkehradresse C rgebnis - i Rückkehradresse rgebnis i Rückkehradresse rgebnis i 0 Rückkehradresse C /
Lösung : acktracking mit Rekursion uf einem n n Schachbrett soll eine Konfiguration gefunden werden, wo genau eine ame in jeder Zeile steht und keine ame eine andere bedroht. ine ame auf einem eld wird genau dann nicht bedroht, wenn sich keine ame in der gleichen Zeile, in der gleichen Spalte oder diagonal befindet. eispiele für n=4, eine ame ist jeweils durch markiert: 0 0 Gegenseitige edrohungen: keine 0 0 ie beiden amen in Zeile 0 bedrohen sich gegenseitig ie beiden amen in Spalte bedrohen sich gegenseitig ie amen in den Positionen (0,) und (,0) bedrohen sich gegenseitig ie amen in den Positionen (0,) und (,) bedrohen sich gegenseitig In dem folgenden Java-Programm fehlt noch die Methode plaziere, die Sie im Rahmen dieser ufgabe realisieren sollen. iese Methode soll ab der durch den Parameter gegebenen Zeile eine ame pro Zeile bedrohungsfrei plazieren, unter der Voraussetzung, dass in den vorhergehenden Zeilen bereits je eine ame bedrohungsfrei plaziert wurde. ie Methode plaziere muss jeweils alle elder der Zeile probieren und dann die Methode plaziere für die nächste Zeile rekursiv aufrufen. Wichtig: s genügt, eine amen-elegung zu finden import simpleio.*; public class Schachbrett { static int[][] feld; eld für Schachbrett 0: auf dem eldelement befindet sich keine ame : auf dem eldelement befindet sich eine ame static int feldgroesse; nzahl der lemente pro Zeile und Spalte /* * bedroht ueberprueft, ob bei der aktuellen Schachbrettbelegung das * lement feld[zeile][spalte] bedrohungsfrei gesetzt werden kann * * @return true: feld[zeile][spalte] ist bedroht, kann also * nicht gesetzt werden * false: feld[zeile][spalte] ist nicht bedroht */ public static boolean bedroht(int zeile, int spalte){ /
ie Methode "bedroht" koennen Sie als gegeben voraussetzen. ie Implementierung dieser Methode ist für die ufgabe nicht relevant und wird daher der Übersicht halber hier nicht angegeben /** * plaziere geht davon aus, dass in den Zeilen * bis einschliesslich "zeile"- bereits * je eine ame bedrohungsfrei pro Zeile gesetzt ist. * plaziere versucht, das eld ab der Zeile "zeile" * bedrohungsfrei mit je einer ame * pro Zeile zu besetzen. Wenn dieses gelingt, * wird true abgeliefert, andernfalls false. * * er erste ufruf von plaziere muss sein: * * plaziere(0). * * @param zeile: Zeilenindex der Zeile, die als * naechstes gesetzt werden muss * * @return true: zeile >= feldgroesse, oder * esetzung ohne edrohung ist gefunden * und in feld markiert * false: esetzung nicht moeglich */ public static boolean plaziere(int zeile) { iese Methode ist im Rahmen der ufgabe zu formulieren public static void ausgabe (usgabe a){ a.println(); for (int i=0; i<feld.length; i++) { for (int j=0; j<feld[i].length; j++) a.print(feld[i][j] + " "); a.println(); public static void main(string[] args) { usgabe a = usgabe.oeffnen(); 4/
if (args.length==0) feldgroesse = ; else feldgroesse = Integer.parseInt(args[0]); feld = new int[feldgroesse][feldgroesse]; a.println(); if (plaziere(0)){ a.println("ine Loesung ist:"); ausgabe(a); else { a.println("s gibt keine Loesung!!"); ausgabe(a); chten Sie darauf, dass Sie Ihre Lösung mit genügend Kommentar versehen, damit man die Lösung nachvollziehen kann. Hinweis zum ufwand: s gibt eine Lösung, die einschließlich Kommentar nur aus Zeilen besteht. (0 Punkte) Lösung: public static boolean plaziere(int zeile) { Ueberpruefung, ob das nde des Schachbretts erreicht ist if (zeile>=feldgroesse) return true; alle lemente der Zeile, die nicht bedroht sind, probieren for (int spalte=0; spalte<feldgroesse; spalte++){ if(!bedroht(zeile,spalte)) { lement setzen und naechste Zeile plazieren feld[zeile][spalte] = ; if (plaziere(zeile+)) return true; kein rfolg, d.h. lement zuruecksetzen und naechste Spalte probieren feld[zeile][spalte] = 0; /
alle Spalten haben zu keinem rfolg gefuehrt, d.h. es gibt keine bedrohungsfreie elegung der aktuellen Zeile return false; Lösung : Hashtabelle Gegeben sei die unten abgebildete Hashtabelle, bei der die Schlüssel mit der Hashfunktion h(k) = Querprodukt(k) M O bestimmt werden. ür eine Zahl z = z z...z n wird hierbei definiert: Querprodukt(z z...z n ) = z z... z n ls Kollisionsstrategie wird lineares Sondieren angewandt, d. h. h i (k) = (h i (k)+) MO. a) ügen Sie die Werte 4,, 0 in der angegebenen Reihenfolge in die folgende Hashtabelle ein und geben Sie dabei die nzahl der aufgetretenen Kollisionen an. 0 4 7 0 0 ( Punkte) b) Welches Problem tritt beim Löschen auf, wenn beim vorausgegangenen infügen Kollisionen aufgetreten sind? Wie kann man das Problem lösen? ( Punkte) Lösung: a) infügen der Werte 4,, 0 in der angegebenen Reihenfolge ergibt: infügen der 4 mit h(4) = 4 MO = 4: 0 4 7 0 0 4 infügen der mit h() = MO = (Kollision h () = ( + ) MO =, Kollision h () = ( + ) MO = ): 0 4 7 0 0 4 infügen der 0 mit h(0) = 0 MO = 0 (Kollision h (0) = (0 + ) MO =, Kollision h (0) = ( + ) MO =, Kollision h (0) = ( + ) MO =, Kollision h 4 (0) = ( + ) MO = 4, Kollision h (0) = (4 + ) MO = ): 0 4 7 0 0 4 0 /
b) inträge müssen als gelöscht markiert werden, da sonst mit Kollisionen eingetragene Werte nicht mehr wiedergefunden werden, die Sondierkette ist unterbrochen. lternativ muss die Tabelle so umorganisiert werden, dass die Sondierketten nicht unterbrochen werden Lösung 4: Sortierverfahren a) s seien eine sortierte Liste L und eine unsortierte Liste L 0 gegeben, wobei L sehr lang im Vergleich zu L 0 ist. ine Möglichkeit, die aus den lementen von L und L 0 bestehende Liste zu sortieren, besteht darin, L 0 ans nde von L anzufügen und die so entstandene Liste zu sortieren. Wählen Sie aus den Verfahren Sortieren durch direktes ussuchen, Sortieren durch direktes infügen und Heapsort dasjenige aus, welches diese ufgabe am effizientesten löst und begründen Sie Ihre nt ( Punkte) b) Welche Laufzeit hat Quicksort im Mittel und im schlechtesten all? ( Punkte) c) Wieviele Schlüsselvergleiche benötigt jedes allgemeine Sortierverfahren zum Sortieren von verschiedenen Schlüsseln sowohl im Mittel als auch im schlechtesten all mindestens? ( Punkte) Lösung: a) Von den Verfahren Sortieren durch direktes ussuchen, Sortieren durch direktes infügen und Heapsort ist Sortieren durch direktes infügen das Verfahren, das in diesem all die gute Vorsortierung am besten ausnützt. ie lemente aus der Liste L werden nur einmal durchlaufen, ohne dass Vertauschungen notwendig sind. ie wenigen lemente von L 0 müssen anschließend in den L-Teil durch infügen einsortiert werden. ie anderen Verfahren nutzen die Vorsortierung überhaupt nicht aus. b) im Mittel: O( log()), im schlechtesten all: O( ) c) Ω( log()) Lösung : Minimale Spannende äume Gegeben sei der folgende gewichtete, ungerichtete Graph: 7/
H ühren Sie den lgorithmus von Kruskal zur erechnung eines minimalen Spannenden aumes durch. Geben Sie in jedem Schritt die betrachtete Kante und die einzelnen Teilbäume an. ( Punkte) Lösung: H wählen: /
H wählen: H wählen: /
H verwerfen verwerfen H wählen: H H verwerfen wählen: 0/
H Lösung : Kürzeste Wege Gegeben sei folgender gewichteter Graph G: a) Wenden Sie den lgorithmus von ijkstra für kürzeste Wege auf den Graphen an. er Startknoten sei die. Geben Sie die Zwischenschritte wie in der Vorlesung in einer Tabelle der folgenden rt an: gewählt Randknoten r. ntfernung Vorgänger r. ntfernung Vorgänger.................. ( Punkte) b) ügen Sie eine ungerichtete Kante mit dem Gewicht von Knoten 4 zu Knoten in G ein. ntnehmen Sie jetzt G den kürzesten Weg von Knoten zu Knoten, ohne den lgorithmus aus a) zu verwenden. ( Punkte) Lösung: /
a) gewählt Randknoten r. ntfernung Vorgänger r. ntfernung Vorgänger 0 0 0 4 4 0 0 4 0 0 4 4 0 0 b) - ie ungerichtete Kante mit negativem Gewicht kann unendlich oft hin und her durchlaufen werden. Jedesmal reduziert sich die Gesamtlänge des Weges um eins. ie korrekte nt ist deshalb -. /