Tutoraufgabe 1 (Pilze):

Ähnliche Dokumente
Tutoraufgabe 1 (Pilze):

Tutoraufgabe 1 (Verifikation):

Tutoraufgabe 1 (Zweierkomplement): Lösung: Programmierung WS16/17 Lösung - Übung 2

Programmierung WS12/13 Lösung - Übung 1 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder

Tutoraufgabe 1 (Programmanalyse):

Tutoraufgabe 1 (Programmanalyse):

Informatik II Musterlösung

Informatik B von Adrian Neumann

Algorithmen und Datenstrukturen

Objektorientierte Programmierung OOP Programmieren mit Java

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Informatik I - Programmierung Globalübung Hoare-Kalkül. Thomas Weiler. Fachgruppe Informatik RWTH Aachen. T. Weiler, RWTH Aachen - 1 -

Einstieg in die Informatik mit Java

Probeklausur: Programmierung WS04/05

Einführung Datentypen Verzweigung Schleifen. Java Crashkurs. Kim-Manuel Klein May 4, 2015

Java Cheatsheet. Mehrzeiliger Kommentar (beginnt mit /* und endet mit */)

PIWIN 1 Übung Blatt 5

1. Typen und Literale (6 Punkte) 2. Zuweisungen (6 = Punkte)

Welche Informatik-Kenntnisse bringen Sie mit?

Programmierkurs Java

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Propädeutikum zur Programmierung

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Repetitorium Informatik (Java)

Programmieren I + II Regeln der Code-Formatierung

Vorlesung Programmieren

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Übung Programmierung WS 2007/08 - Blatt 5

Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A

Grundlagen der Programmierung Prof. H. Mössenböck. 4. Schleifen

Es ist für die Lösung der Programmieraufgabe nicht nötig, den mathematischen Hintergrund zu verstehen, es kann aber beim Verständnis helfen.

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

public class SternchenRechteckGefuellt {

Kapitel 9. Komplexität von Algorithmen und Sortieralgorithmen

Einführung in die Programmierung Vorlesungsprüfung

Tutoraufgabe 1 (Überladen von Methoden):

Einführung in die Programmierung 1

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 8. Arrays. Arrays

5. Tutorium zu Programmieren

GI Vektoren

Übungsblatt 4. Java Vorkurs (WS 2015)

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

Einführung in den Einsatz von Objekt-Orientierung mit C++ I

Objektorientierte Programmierung

Übungen zur Vorlesung Einführung in die Informatik Wintersemester 2010/11

AuD-Tafelübung T-B5b

3. Anweisungen und Kontrollstrukturen

Dr. Monika Meiler. Inhalt

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung

RO-Tutorien 3 / 6 / 12

6 Speicherorganisation

Technische Universität Braunschweig Institut für Programmierung und Reaktive Systeme

1. Grundzüge der Objektorientierung 2. Methoden, Unterprogramme und Parameter 3. Datenabstraktion 4. Konstruktoren 5. Vordefinierte Klassen

6. Iteration (Schleifenanweisungen)

Programmieren I. Kapitel 5. Kontrollfluss

Einführung in die Programmierung für Wirtschaftsinformatik

Probeklausur: Programmierung WS04/05

Grundzüge der Wirtschaftsinformatik WS 2002/03. Wiederholung Java. Programmierzyklus. Heiko Rossnagel Problem

PROGRAMMIERUNG IN JAVA

Übung Grundlagen der Programmierung. Übung 03: Schleifen. Testplan Testergebnisse

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Modul Entscheidungsunterstützung in der Logistik. Einführung in die Programmierung mit C++ Übung 2

Tutoraufgabe 1 (2 3 4 Bäume):

Software Engineering Klassendiagramme Einführung

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

1. Erste Schritte 2. Einfache Datentypen 3. Anweisungen und Kontrollstrukturen 4. Verifikation 5. Reihungen (Arrays)

II.3.1 Rekursive Algorithmen - 1 -

Greenfoot: Verzweigungen

Einführung in die Informatik

Wiederholung Wozu Methoden? Methoden Schreiben Methoden Benutzen Rekursion?! Methoden. Javakurs 2012, 3. Vorlesung

Studentische Lösung zum Übungsblatt Nr. 7

Reihungen. Martin Wirsing. in Zusammenarbeit mit Matthias Hölzl und Nora Koch 11/03

Einstieg in die Informatik mit Java

Nachholklausur (6 ECTS) Einführung in die Informatik: Programmierung und Software-Entwicklung. Nachname... Vorname... Matrikelnummer... Studienfach...

Kapitel 3: Variablen

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Allgemeine Informatik 2 im SS 2007 Programmierprojekt

Sie müssen den Test bis 20:00 Uhr am Abgabetag dieses Übungszettels absolviert haben.

Allgemeine Hinweise: TECHNISCHE UNIVERSITÄT MÜNCHEN. Name Vorname Studiengang Matrikelnummer. Hörsaal Reihe Sitzplatz Unterschrift

Übersicht. Schleifen. Schleifeninvarianten. Referenztypen, Wrapperklassen und API. 9. November 2009 CoMa I WS 08/09 1/15

Primitive Datentypen

Grundlagen der Programmierung Prof. H. Mössenböck. 10. Klassen

Fachgebiet Informationssysteme Prof. Dr.-Ing. N. Fuhr. Programmierung Prof. Dr.-Ing. Nobert Fuhr. Übungsblatt Nr. 6

Java-Implementierung der Priority-Queue und des Huffman-Algorithmus Effiziente Algorithmen SS12 Übung 4 Aufgabe 5 Johannes Hein

! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4.

Übersicht. Informatik 2 Teil 3 Anwendungsbeispiel für objektorientierte Programmierung

Letztes Mal. static int ggt(int a, int b) { if (a == b) return a; else if (a > b) return ggt(a-b,b); else if (a < b) return ggt(a,b-a);

Java Kurzreferenz Für Fortgeschrittene

1.2 Attribute und Methoden Aufbau einer Java-Klasse:

Objektorientierung II

Objektorientierte Programmierung

5.4 Klassen und Objekte

Praktikum aus Programmierung Dr. Michael Hahsler (WS 05/06) Projekt: Würfelpoker

Übersicht. Berechnung der Potenz für zwei ganze Zahlen Klausuraufgabe SS 2010! Berechnung der Cosinus-Funktion Klausuraufgabe WS 2010/2011!

Kapitel 5: Abstrakte Algorithmen und Sprachkonzepte. Elementare Schritte

Aufgabenblatt 1: - Präsenzübung für die Übungen Do Mi Ausgabe Mi

Übungen zur Vorlesung EidP (WS 2015/16) Blatt 6

Transkript:

Prof. aa Dr. J. Giesl Programmierung WS14/15 C. Aschermann, F. Frohn, J. Hensel, T. Ströder Tutoraufgabe 1 (Pilze): In dieser Aufgabe beschäftigen wir uns mit dem berühmten Gaunerpärchen Bonnie und Clyde. Wenn die beiden nicht gerade Banken ausrauben, gehen sie gerne im Wald Pilze sammeln (bzw. klauen). Wir verwenden hier die Klassen Main, Mensch und Pilz, die Sie auf der Homepage herunterladen können. Jeder dieser (beiden) Menschen hat einen Korb, in den eine feste Anzahl von Pilzen passt. Weiterhin hat jeder Mensch einen Namen. Wie Sie in der Klasse Mensch sehen können, gibt es hierfür drei Attribute. Das Attribut anzahl gibt hierbei an, wie viele Pilze bereits im Korb enthalten sind. Zu jedem Pilz kennen wir den Namen. a) Vervollständigen Sie die Klasse Main wie folgt: Ergänzen Sie an den mit TODO a.1) markierten Stellen den Code so, dass die Variablen steinpilz, champignon, pfifferling auf Pilz-Objekte mit passenden Namen verweisen. Ergänzen Sie an den mit TODO a.2) markierten Stellen den Code so, dass die Variablen bonnie und clyde auf passende Mensch-Objekte zeigen. Setzen Sie hierfür jeweils den passenden Namen und sorgen Sie dafür, dass in Bonnies Korb maximal 3 Pilze Platz haben. Bei Clyde passen 4 Pilze in den Korb. b) Gehen Sie in dieser Teilaufgabe davon aus, dass die Attribute bereits alle auf vernünftige Werte gesetzt sind. Erweitern Sie die Klasse Mensch um eine Methode hatplatz(), die true genau dann zurückgibt, wenn im Korb Platz für einen weiteren Pilz ist. Anderenfalls wird false zurückgegeben. Schreiben Sie für die Klasse Mensch eine Methode ausgabe(). Diese gibt kein Ergebnis zurück, aber gibt den Namen und eine lesbare Übersicht der von der Person gesammelten Pilze aus. Geben Sie in der ersten Zeile den Namen der Person gefolgt von einem Doppelpunkt (:) aus. Schreiben Sie pro Pilz im Korb eine weitere Zeile, in der (nur) der Name des jeweiligen Pilzes steht. Eine Beispielausgabe von einem Menschen mit Namen Gustav und einem Korb, der einen Pilz mit Namen Morchel und einen Pilz mit Namen Steinpilz enthält: Gustav: Morchel Steinpilz c) In der Klasse Main sehen Sie eine Variable wald. Schreiben Sie an die mit TODO c) markierte Stelle eine Schleife, die die Pilze im wald-array nach und nach abarbeitet. Hierbei wird zuerst überprüft, ob Bonnie Platz für einen weiteren Pilz hat. Wenn dies der Fall ist, wird der Pilz in Bonnies Korb hinzugefügt. Benutzen Sie hierfür auch das Attribut anzahl und passen Sie dieses entsprechend an. Nur wenn der Pilz bei Bonnie nicht hinzugefügt werden konnte, probieren wir den Pilz bei Clyde hinzuzufügen. Überprüfen Sie also in diesem Fall ebenfalls, ob der Korb voll ist und fügen Sie den Pilz ggf. hinzu. Wenn ein Pilz weder bei Bonnie noch bei Clyde hinzugefügt werden kann, wird der Pilz keinem Korb hinzugefügt. Rufen Sie am Ende einer jeder Schleifeniteration die Methode ausgabe() zuerst für Bonnie und anschlieÿend für Clyde auf. Geben Sie anschlieÿend eine Zeile aus, in der nur - - - (drei Bindestriche) steht. 1

Listing 1: Main.java 1 public class Main { 2 public static void main ( String [] args ) { 3 Pilz steinpilz = // TODO a.1) 4 5 Pilz champignon = // TODO a.1) 6 7 Pilz pfifferling = // TODO a.1) 8 9 Mensch bonnie = // TODO a.2) 10 11 Mensch clyde = // TODO a.2) 12 13 Pilz [] wald = new Pilz [] { steinpilz, champignon, champignon, pfifferling, 14 steinpilz, pfifferling, champignon ; 15 16 // TODO c) 17 18 1 public class Mensch { 2 String name ; 3 Pilz [] korb ; 4 int anzahl = 0; 5 Listing 2: Mensch.java 1 public class Pilz { 2 String name ; 3 Listing 3: Pilz.java Lösung: Listing 4: Main.java 1 public class Main { 2 public static void main ( String [] args ) { 3 Pilz steinpilz = new Pilz (); 4 steinpilz. name = " Steinpilz "; 5 6 Pilz champignon = new Pilz (); 7 champignon. name = " Champignon "; 8 9 Pilz pfifferling = new Pilz (); 10 pfifferling. name = " Pfifferling "; 11 12 Mensch bonnie = new Mensch (); 13 bonnie. name = " Bonnie "; 14 bonnie. korb = new Pilz [3]; 15 16 Mensch clyde = new Mensch (); 17 clyde. name = " Clyde "; 18 clyde. korb = new Pilz [4]; 19 20 Pilz [] wald = new Pilz [] { steinpilz, champignon, champignon, pfifferling, 21 steinpilz, pfifferling, champignon ; 22 23 for ( Pilz pilz : wald ) { 24 if ( bonnie. hatplatz ()) { 25 bonnie. korb [ bonnie. anzahl ] = pilz ; 26 bonnie. anzahl ++; 27 else if ( clyde. hatplatz ()) { 2

28 clyde. korb [ clyde. anzahl ] = pilz ; 29 clyde. anzahl ++; 30 31 bonnie. ausgabe (); 32 clyde. ausgabe (); 33 System. out. println (" ---" ); 34 35 36 Listing 5: Mensch.java 1 public class Mensch { 2 String name ; 3 Pilz [] korb ; 4 int anzahl = 0; 5 6 public boolean hatplatz () { 7 return anzahl < korb. length ; 8 9 10 public void ausgabe () { 11 System. out. println ( name + ": " ); 12 for ( Pilz pilz : korb ) { 13 if ( pilz!= null ) { 14 System. out. println ( pilz. name ); 15 16 17 18 Listing 6: Pilz.java 1 public class Pilz { 2 String name ; 3 Tutoraufgabe 3 (Spielfeld): In dieser Tutoraufgabe soll die Ausgabe eines Spielfelds als Java-Programm implementiert werden. Hierzu existiert bereits eine Klasse Feld mit einem Attribut fieldsize, das die Seitenlänge des quadratischen Spielfelds angibt. Listing 7: Feld.java 1 public class Feld { 2 3 // Seitenlaenge des quadratischen Spielfeldes 4 public static int fieldsize = 10; 5 6 // Gibt das Spielfeld aus. 7 public static void ausgabe ( 8 boolean [][] spieler1, 9 boolean [][] spieler2 ) 10 { 11 // TODO 12 13 14 15 // Fuehrt das Programm aus. 16 public static void main ( String [] args ) { 17 Feld. fieldsize = 3; 18 boolean [][] p1 = {{ true, true, true, 19 { false, false, false, 20 { false, false, false ; 3

21 boolean [][] p2 = {{ true, false, false, 22 { true, false, false, 23 { true, false, true ; 24 ausgabe (p1, p2 ); 25 26 Implementieren Sie die Methode ausgabe in der Klasse Feld. Diese Methode bekommt zwei 2-dimensionale Arrays von booleans als Eingabe, die das Spielfeld darstellen. Ein Feld (x, y) auf dem Spielfeld wird mit O beschriftet, falls nur Spieler 1 auf dieses Feld gesetzt hat (d.h., falls spieler1[x][y] == true). Falls nur Spieler 2 auf das Feld gesetzt hat, wird ein X angezeigt. Haben beide Spieler auf dasselbe Feld gesetzt, so wird @ ausgegeben. Freie Felder werden mit einem (Space) angezeigt. Die Ausführung der main Methode der Klasse Feld sollte dann folgende Ausgabe erzeugen. 0 1 2 -+ -+ -+ -+ A @ O O -+ -+ -+ -+ B X -+ -+ -+ -+ C X X -+ -+ -+ -+ Lösung: Listing 8: Feld.java 1 public class Feld { 2 3 // Seitenlaenge des quadratischen Spielfeldes 4 public static int fieldsize = 10; 5 6 // Gibt das Spielfeld aus. 7 public static void ausgabe ( 8 boolean [][] spieler1, 9 boolean [][] spieler2 ) 10 { 11 // 0- Indizes werden fuer Beschriftung genutzt, Array - Indizes sind 12 // um 1 verschoben 13 for ( int i = 0; i <= Feld. fieldsize ; i++) { 14 for ( int j = 0; j <= Feld. fieldsize ; j++) { 15 if (i > 0) { 16 if (j > 0) { 17 // wir sind im Spielfeld 18 boolean sp1 = spieler1 [i - 1][ j - 1]; 19 boolean sp2 = spieler2 [i - 1][ j - 1]; 20 if ( sp1 ) { 21 System. out. print ( sp2? "@" : "O" ); 22 else { 23 System. out. print ( sp2? "X" : " " ); 24 25 else { 26 // wir sind in der Zeilenbeschriftung (j == 0) 27 System. out. print (( char ) (64 + i )); 28 29 else { 30 // wir sind in der Spaltenbeschriftung (i == 0) 31 // fuer j == 0 wird ein Leerzeichen ausgegeben 32 System. out. print (j > 0? j - 1 : " " ); 33 34 // nach jedem Eintrag kommt ein Trennsymbol 35 System. out. print (" " ); 36 37 // nach jeder Zeile kommt ein Zeilenumbruch 38 System. out. println (); 39 // und anschliessend eine Trennzeile 40 Feld. linie ( Feld. fieldsize ); 41 42 // zur Abgrenzung weiterer Ausgaben wird ein zusaetzlicher 43 // Zeilenumbruch am Ende hinzugefuegt 44 System. out. println (); 45 4

46 47 48 // Gibt eine Zeile mit length + 1 vielen " -+" - en aus. 49 public static void linie ( int length ) { 50 for ( int i = 0; i <= length ; i++) { 51 System. out. print (" -+" ); 52 53 System. out. println (); 54 55 56 // Fuehrt das Programm aus. 57 public static void main ( String [] args ) { 58 Feld. fieldsize = 3; 59 boolean [][] p1 = {{ true, true, true, { false, false, false, { false, false, false ; 60 boolean [][] p2 = {{ true, false, false, { true, false, false, { true, false, true ; 61 ausgabe (p1, p2 ); 62 63 Tutoraufgabe 5 (Veranstaltungen): In dieser Aufgabe soll ein Programm betrachtet werden, das bei der Organisation des Übungsbetriebs einer Lehrveranstaltung hilft. Zu einer Lehrveranstaltung gehören verschiedene Tutorien, wobei ein Tutorium aus mehreren Studenten zusammengesetzt ist. Jeder Student hat einen Namen und eine Matrikelnummer. Der Einfachheit halber verwenden wir in dieser Aufgabe genau zwei Tutorien, die als Arrays von Studenten dargestellt sind. Diese Zusammenhänge erkennt man an den entsprechenden Teilen der Klassendeklarationen: public class Veranstaltung { Student [] tutoriumeins ; Student [] tutoriumzwei ;... public class Student { String name ; int matrikelnummer ;... Startet man die main-methode in der Klasse Veranstaltung, werden zu Beginn in der Methode init() die beiden Tutorien-Arrays vom Typ Student[] mit neuen Student-Objekten gefüllt. Jedem Studenten wird dabei ein Name und eine Matrikelnummer zugewiesen. Anschlieÿend wird die Methode tauschen() aufgerufen, mit der man die Tutorien zweier Studenten einfach tauschen kann. Hierfür wird der Benutzer pro Tutorium nach einem Studenten gefragt, der tauschen möchte. Tutorium 1: 1: Hans Wurst (356789) 2: Lisa Lachs (346879) Tutorium 2: 1: Simone Schnitzel (361030) 2: Peter Pute (357001) Welcher Student aus Tutorium 1 möchte tauschen? (0 zum Beenden) 2 Welcher Student aus Tutorium 2 möchte tauschen? 1 Sobald der Benutzer die letzte Eingabe (im Beispiel 1) bestätigt, werden die beiden Studierenden (im Beispiel Lisa Lachs aus Gruppe 1 und Simone Schnitzel aus Gruppe 2) getauscht und das Ergebnis ausgegeben. Anschlieÿend ist ein weiterer Tauschvorgang möglich. Sie nden die benötigten Dateien Veranstaltung.java und Student.java auf der Webseite zur Vorlesung. 1 public class Veranstaltung { 2 Student [] tutoriumeins ; 3 Student [] tutoriumzwei ; Listing 9: Veranstaltung.java 5

4 5 public static void main ( String [] args ) { 6 Veranstaltung v = new Veranstaltung (); 7 v. init (); 8 v. tauschen (); 9 10 11 public void init () { 12 tutoriumeins = new Student [ 2]; 13 tutoriumzwei = new Student [ 2]; 14 15 Student hans = new Student (); 16 hans. name = " Hans Wurst "; 17 hans. matrikelnummer = 356789; 18 tutoriumeins [0] = hans ; 19 20 Student lisa = new Student (); 21 lisa. name = " Lisa Lachs "; 22 lisa. matrikelnummer = 346879; 23 tutoriumeins [1] = lisa ; 24 25 // Speicherzustand, nachdem ein Tutorium gefuellt wurde 26 27 Student simone = new Student (); 28 simone. name = " Simone Schnitzel "; 29 simone. matrikelnummer = 361030; 30 tutoriumzwei [0] = simone ; 31 32 Student peter = new Student (); 33 peter. name = " Peter Pute "; 34 peter. matrikelnummer = 357001; 35 tutoriumzwei [1] = peter ; 36 37 38 public void ausgabe ( Student [] tutorium ) { 39 40 41 public void tauschen () { 42 // tausche die Tutorien einiger Studis 43 int indexa ; 44 do { 45 System. out. println (" Tutorium 1: " ); 46 for ( int i = 0; i < tutoriumeins. length ; i ++) { 47 Student studi = tutoriumeins [ i ]; 48 System. out. print (( i +1) + ": " ); 49 if ( studi == null ) { 50 System. out. println (); 51 else { 52 studi. ausgabe (); 53 54 55 System. out. println (" Tutorium 2: " ); 56 for ( int i = 0; i < tutoriumzwei. length ; i ++) { 57 Student studi = tutoriumzwei [ i ]; 58 System. out. print (( i +1) + ": " ); 59 if ( studi == null ) { 6

60 System. out. println (); 61 else { 62 studi. ausgabe (); 63 64 65 66 System. out. println (" Welcher Student aus Tutorium 1 moechte tauschen? (0 zum Been 67 indexa = Integer. parseint ( System. console (). readline ()); 68 if ( indexa!= 0) { 69 System. out. println (" Welcher Student aus Tutorium 2 moechte tauschen?" ); 70 int indexb = Integer. parseint ( System. console (). readline ()); 71 72 // hole Studenten aus erster Gruppe 73 Student ausa = tutoriumeins [ indexa - 1]; 74 // hole Studenten aus zweiter Gruppe 75 Student ausb = tutoriumzwei [ indexb - 1]; 76 // speichere Studenten in erster Gruppe 77 tutoriumeins [ indexa -1] = ausb ; 78 // speichere Studenten in zweiter Gruppe 79 tutoriumzwei [ indexb -1] = ausa ; 80 81 // Speicherzustand nach Tausch Lisa Lachs und Simone Schnitzel 82 83 while ( indexa > 0); 84 85 Listing 10: Student.java 1 public class Student { 2 String name ; 3 int matrikelnummer ; 4 5 public void ausgabe () { 6 System. out. println ( name + " (" + matrikelnummer + ")" ); 7 8 a) Wir betrachten den Zeitpunkt, zu dem das erste der beiden Tutorien initialisiert und mit Studenten gefüllt wurde. In der Klasse Veranstaltung ist in der Methode init() eine entsprechende Markierung als Kommentar vorhanden. Visualisieren Sie zu diesem Zeitpunkt den Zustand des Programms, bestehend aus beiden Arrays und allen Objekte der Klasse Student. b) Visualisieren Sie den Zustand des Programs, nachdem die entsprechende Tauschoperation durchgeführt wurde. In der Klasse Veranstaltung ist in der Methode tauschen() eine entsprechende Markierung als Kommentar vorhanden. Lösung: a) Der Speicher sieht nach Initialisierung des Arrays tutoriumeins wie folgt aus: 7

8

b) Nach dem Tausch der beiden Studenten sieht der Speicher wie folgt aus: Tutoraufgabe 7 (Verikation mit Arrays): Gegeben sei folgendes Java-Programm P : a.length > 0 (Vorbedingung) res = a[0]; i = 1; while (i < a.length) { if (a[i] > res) { res = a[i]; i = i + 1; res = max{ a[j] 0 j < a.length (Nachbedingung) a) Vervollständigen Sie die folgende Verikation des Algorithmus im Hoare-Kalkül, indem Sie die unterstrichenen Teile ergänzen. Hierbei dürfen zwei Zusicherungen nur dann direkt untereinander stehen, wenn die untere aus der oberen folgt. Hinter einer Programmanweisung darf nur eine Zusicherung stehen, wenn dies aus einer Regel des Hoare-Kalküls folgt. Beachten Sie bei der Anwendung der Bedingungsregel 1 mit Vorbedingung ϕ und Nachbedingung ψ, dass ϕ B = ψ gelten muss. D. h. die Nachbedingung der if-anweisung ψ muss aus der Vorbedingung der if-anweisung ϕ und der negierten Bedingung B selbst folgen. Geben Sie beim Verwenden der Regel einen entsprechenden Beweis an. Hinweise: Sie dürfen beliebig viele Zusicherungs-Zeilen ergänzen oder streichen. In der Musterlösung werden allerdings genau die angegebenen Zusicherungen benutzt. Bedenken Sie, dass die Regeln des Kalküls syntaktisch sind, weshalb Sie semantische Änderungen (beispielsweise von x+1 = y+1 zu x = y) nur unter Zuhilfenahme der Konsequenzregeln vornehmen dürfen. 9

b) Untersuchen Sie den Algorithmus P auf seine Terminierung. Für einen Beweis der Terminierung muss eine Variante angegeben werden und unter Verwendung des Hoare-Kalküls die Terminierung unter der Voraussetzung a.length > 0 bewiesen werden. Geben Sie auch bei dieser Teilaufgabe einen Beweis für die Aussage ϕ B = ψ bei der Anwendung der Bedingungsregel 1 an. Lösung: a) Mit Hilfe der Schleife wird das Array a von der zweiten Stelle (a[1]) bis zur letzten Stelle a.length 1 durchlaufen. Die Variable res wird mit dem Wert der ersten Stelle des Arrays initialisiert und somit gilt res = max{ a[j] 0 j < 1. Im Schleifenkörper wird der Wert von res so angepasst, dass der nächstgröÿere Index des Arrays mit betrachtet wird. So kann man die Aussage zu res = max{ a[j] 0 j < i verallgemeinern (alternativ lässt sich die obere Grenze a.length in der Nachbedingung durch die Laufvariable i ersetzen). Um mit der negierten Schleifenbedingung (i < a.length) die Nachbedingung folgern zu können, brauchen wir zusätzlich noch die Aussage, dass nach dem Schleifendurchlauf i = a.length gilt. Dies können wir folgern, wenn wir zu der bisherigen Invariante i a.length hinzufügen. So ergibt sich die Schleifeninvariante i a.length res = max{ a[j] 0 j < i (diese Begründung war nicht gefordert und dient nur zur Erklärung der Musterlösung). 10

a.length > 0 a.length > 0 a[0] = a[0] 1 = 1 res = a[0]; a.length > 0 res = a[0] 1 = 1 i = 1; a.length > 0 res = a[0] i = 1 i a.length res = max{ a[j] 0 j < i while (i < a.length) { i a.length res = max{ a[j] 0 j < i i < a.length i + 1 a.length res = max{ a[j] 0 j < i if (a[i] > res) { i + 1 a.length res = max{ a[j] 0 j < i a[i] > res i + 1 a.length a[i] = max{ a[j] 0 j < i + 1 res = a[i]; i + 1 a.length res = max{ a[j] 0 j < i + 1 i + 1 a.length res = max{ a[j] 0 j < i + 1 i = i + 1; i a.length res = max{ a[j] 0 j < i i a.length res = max{ a[j] 0 j < i (i < a.length) res = max{ a[j] 0 j < a.length Damit die Bedingungsregel angewendet werden darf, muss überprüft werden, dass aus i+1 a.length res = max{ a[j] 0 j < i (a[i] > res) die Aussage i + 1 a.length res = max{ a[j] 0 j < i + 1 folgt. Dies ist allerdings oensichtlich: Da (a[i] > res) gilt, ändert sich die Gröÿe des max-terms nicht, falls das Element a[i] zusätzlich berücksichtigt wird. b) Eine gültige Variante für die Terminierung ist V = a.length i, denn die Schleifenbedingung B = i < a.length impliziert a.length i 0 und es gilt: if (a[i] > res) { res = a[i]; i = i + 1; a.length i = m i < a.length a.length (i + 1) < m a.length (i + 1) < m a[i] > res a.length (i + 1) < m a.length (i + 1) < m a.length (i + 1) < m a.length i < m Damit die Bedingungsregel angewendet werden darf, muss überprüft werden, dass aus a.length (i + 1) < m (a[i] > res) die Aussage a.length (i + 1) < m folgt. Dies ist allerdings oensichtlich. Damit ist die Terminierung der einzigen Schleife in P gezeigt. 11