Übung zur Vorlesung Programmierung

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

Folge 18 - Vererbung

Informatik II Musterlösung

Geordnete Binärbäume

Institut für Informatik

Probeklausur: Programmierung WS04/05

Tutoraufgabe 1 (2 3 4 Bäume):

Aufgabenblatt Nr. 5 Generizität und TicTacToe

Einführung in die Programmierung

Programmierkurs Java

Einführung Elementare Datenstrukturen. Der Konstruktor muß den Listenkopf head erzeugen. Der Vorgänger und Nachfolger von head ist head selbst.

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 13. Bäume. Bäume

Objektorientierte Programmierung

Informatik 11 Kapitel 2 - Rekursive Datenstrukturen

Objektorientierte Programmierung

Einstieg in die Informatik mit Java

Objektorientierte Programmierung

Inhalte Informatik. I1 Grundprinzip des objektorientierten Modellierens I3 Modellieren von Netzwerkanwendungen

Versuchsziele. Grundlagen. Überblick: FB Automatisierung und Informatik Betriebssysteme Thema: Bounded-Buffer-Problem. 3.

Probeklausur zur Vorlesung Berechenbarkeit und Komplexität

Studentische Lösung zum Übungsblatt Nr. 7

JAVA KURS COLLECTION

Abstrakte Datentypen.

Probeklausur: Programmierung WS04/05

Verkettete Listen. Implementierung von einfach verketteten Listen. Implementierung von doppelt verketteten Listen

Selbststudium OOP4 Auftrag

Folge 19 - Bäume Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12

5. Tutorium zu Programmieren

Kapitel 5: Abstrakte Algorithmen und Sprachkonzepte. Elementare Schritte

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Objektorientierte Programmierung OOP Programmieren mit Java

PIWIN 1 Übung Blatt 5

Repetitorium Informatik (Java)

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

Algorithmen und Datenstrukturen

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Programmierstil. Objektsammlungen. Konzepte. Zwischenspiel: Einige beliebte Fehler... Variablennamen Kommentare Layout Einrückung

Einführung in die Programmierung Vorlesungsprüfung

In dieser Aufgabe sollen Teile eines kleinen Pong-Spiels analysiert und implementiert werden. Gegeben sei dazu das folgende Szenario:

Grundkonzepte java.util.list

Java Einführung Collections

Jetzt sollt ihr von der Vorlage der Grundversion 1.0 ein eigenes Textadventure erstellen.

1 Polymorphie (Vielgestaltigkeit)

1.2 Attribute und Methoden Aufbau einer Java-Klasse:

Einführung in die Programmierung für Wirtschaftsinformatik

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

equals und hashcode SortedSet NavigableSet Assoziative Container Programmieren II Dr. Klaus Höppner Hochschule Darmstadt Sommersemester / 32

Der linke Teilbaum von v enthält nur Schlüssel < key(v) und der rechte Teilbaum enthält nur Schlüssel > key(v)

UNIVERSITÄT ULM Fakultät für Ingenieurswissenschaften und Informatik Institut für Datenbanken und Informationssysteme

Einführung in die Informatik

Java. Wir verwenden oft Java für Datenstrukturen und Algorithmen. Die Vorlesung ist aber von der Programmiersprache unabhängig.

Suchbäume. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Schritt 1 - Ein Spielfeld

Verteilte Systeme CS5001

Suchen und Sortieren

JAVA - Methoden

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

Teil V. Generics und Kollektionen in Java

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

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

Übung zur Vorlesung Berechenbarkeit und Komplexität

Eine Klasse beschreibt Objekte mit gleichen Attributen und Methoden.

Grundlagen der Informatik Generische Klassen

Arrays Fortgeschrittene Verwendung

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

Arrays von Objekten. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Programmierung mit C Zeiger

5.4 Klassen und Objekte

Testklausur 2 zur Vorlesung. Modellierung und Programmierung I. Dr. Monika Meiler Zeit: 60 Minuten

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

Einführung in die Informatik Control Structures and Enumerations

Übungspaket 31 Entwicklung eines einfachen Kellerspeiches (Stacks)

Kapitel 6. Vererbung

Übungen zu Programmierung I - Blatt 8

Einführung in Javadoc

Name: Klausur Programmierkonzepte SS 2011

Kapitel 6. Vererbung

Computeranwendung und Programmierung (CuP)

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

EINI WiMa/LW. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 11/12

Java II - Übungsgruppe

Java Schulung. Objektorientierte Programmierung in Java Teil V: Die Java Collection Klassen. Prof. Dr. Nikolaus Wulff

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

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

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

Thread-Synchronisation in in Java. Threads Wechselseitiger Ausschluss Bedingte Synchronisation Beispiel: Warteschlangen

14. Rot-Schwarz-Bäume

Fakultät Angewandte Informatik Programmierung verteilter Systeme Übungen zur Vorlesung Informatik II, Blatt 6

Tutoraufgabe 1 (Überladen von Methoden):

AVL-Bäume Analyse. Theorem Ein AVL-Baum der Höhe h besitzt zwischen F h und 2 h 1 viele Knoten. Definition Wir definieren die nte Fibonaccizahl:

Selbsteinstufungstest Vorkurs Programmieren

Bäume. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 10: Collections 4. Inhalt. Bäume. Einführung. Bäume.

Sortieralgorithmen. Inhalt: InsertionSort BubbleSort QuickSort. Marco Block

Vorkurs C++ Programmierung

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

Klassen mit Instanzmethoden

Kapitel 2: Analyse der Laufzeit von Algorithmen Gliederung

5.5.8 Öffentliche und private Eigenschaften

Programmieren in Java

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

Transkript:

RWTH Aachen Lehrgebiet Theoretische Informatik Frohn Reidl Rossmanith Sánchez Ströder WS 013/14 Übungsblatt 4 18.11.013 Übung zur Vorlesung Programmierung Aufgabe T8 Ein Stack ist eine Datenstruktur, die stets nur Zugriff auf das zuletzt eingefügte Element ermöglicht. Folglich stellt ein Stack in der Regel Funktionen zum Ablegen eines Elementes (push) und zum Zugriff auf das zuletzt abgelegte Element (pop, peek) zur Verfügung. Implementieren Sie eine Klasse Stack, die eine veränderbare 1 Implementierung der Datenstruktur Stack für nicht negative ganze Zahlen mit folgenden Methoden zur Verfügung stellt: void push(int x): Legt das Element x auf dem Stack ab. Wenn x negativ ist, dann bleibt der Stack unverändert. int pop(): Entfernt das zuletzt abgelegte Element vom Stack und liefert dieses zurück. Falls der Stack leer ist, wird 1 zurückgegeben. int peek(): Liefert das zuletzt abgelegte Element zurück, ohne es zu entfernen. Falls der Stack leer ist, wird 1 zurückgegeben. Eine Queue ist eine Datenstruktur, die stets nur Zugriff auf jenes Element ermöglicht, das am längsten Teil der Queue ist. Folglich stellt eine Queue in der Regel Funktionen zum Einfügen eines neuen Elements (enqueue) und zum Zugriff auf das älteste Element (dequeue) zur Verfügung. Implementieren Sie eine Klasse Queue, die eine veränderbare Implementierung der Datenstruktur Queue für nicht negative ganze Zahlen mit folgenden Methoden zur Verfügung stellt: void enqueue(int x): Fügt das Element x zu der Queue hinzu. Wenn x negativ ist, dann bleibt die Queue unverändert. int dequeue(): Entfernt das älteste Element aus der Queue und liefert dieses zurück. Falls die Queue leer ist, wird -1 zurückgegeben. 1 Das heißt Methoden, die den Stack verändern, manipulieren die Stack-Instanz, auf der die Methode aufgerufen wurde, statt neue Instanzen zu erzeugen.

Lösungsvorschlag class Stack { private Entry head; public boolean isempty() { return this.head == null; public void push(int i) { if (i < 0) return; this.head = new Entry(i, this.head); public int pop() { if (this.isempty()) return 1; int res = this.head.getvalue(); this.head = this.head.getnext(); return res; public int peek() { if (this.isempty()) return 1; return this.head.getvalue(); class Entry { private int value; private Entry next; Entry(int v,entry n) { this.value = v; this.next = n; int getvalue() { return this.value; Entry getnext() { return this.next; void setnext(entry n) { this.next = n; class Queue { private Entry head; private Entry last; public void enqueue(int i) { if (i < 0) return; Entry oldhead = this.head; this.head = new Entry(i,null); if (oldhead! = null) oldhead.setnext(this.head); else this.last = this.head;

public boolean isempty() { return this.last == null; public int dequeue() { if (this.isempty()) return 1; int res = this.last.getvalue(); this.last = this.last.getnext(); if (this.last == null) this.head = null; return res; Aufgabe T9 Gegeben sei folgendes Java-Programm P: ϕ (Vorbedingung) r = 1; while (r * r < x){ r = r + 1; ψ (Nachbedingung) a) Als Vorbedingung ϕ für das oben aufgeführte Programm P gelte x > 0 und als Nachbedingung ψ gelte r = x. Vervollständigen Sie die folgende Verifikation des Algorithmus, indem Sie die leeren Zeilen durch korrekte Zusicherungen entsprechend des Hoare-Kalküls 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. x > 0 r = 1; while (r * r < x){ hierbei ist x die ganzzahlige Aufrundung von x; siehe auch http://de.wikipedia.org/wiki/abrundungsfunktion und Aufrundungsfunktion

r = r + 1; r = x 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. b) Untersuchen Sie den Algorithmus P auf seine Terminierung. Für einen Beweis der Terminierung muss eine Variante angegeben werden und mit Hilfe des Hoare-Kalküls die Terminierung bewiesen werden. Hinweis: Sie dürfen für den Terminierungsbeweis zusätzlich zur Schleifenbedingung auch r > 0 zu Beginn jedes Schleifendurchlaufs annehmen. Lösungsvorschlag a) x > 0 x > 0 1 = 1 r = 1; x > 0 r = 1 (r 1) < x r > 0 while (r * r < x){ (r 1) < x r > 0 r < x (r + 1 1) < x r+1 > 0 r = r + 1; (r 1) < x r > 0 (r 1) < x r > 0 (r < x) r = x Der folgende Teil dient lediglich zur Erklärung und ist für die Lösung der Aufgabe nicht erforderlich. Er zeigt genau, welche einzelnen Regeln des Kalküls in der obigen Lösung verwendet wurden, um die Korrektheit von P zu zeigen.

x > 0 0 = 0 r = 1; x > 0 r = 1 Zuweisung x > 0 r = 1; x > 0 r = 1 Konsequenz 1 Konsequenz x > 0 r = 1; (r 1) < x r > 0 (r 1) < x r > 0 while (r * r < x) {r = r + 1; r = x Zuweisung (r + 1 1) < x r + 1 > 0 {r = r + 1; (r 1) < x r > 0 Konsequenz 1 (r 1) < x r > 0 r < x {r = r + 1; (r 1) < x r > 0 Schleife (r 1) < x r > 0 while (r * r < x) {r = r + 1; (r 1) < x r > 0 r x x > 0 r = 1; while (r * r < x) {r = r + 1; r = x Konsequenz Sequenz b) Wir wählen als Variante V = x r. Hiermit lässt sich die Terminierung von P beweisen, denn für die einzige Schleife im Programm (mit Schleifenbedingung B = r < x und Schleifenkörper r = r + 1;) gilt: B V 0, denn B r < x x r > 0 V > 0 und x r = m r < x r > 0 x (r + 1) < m r = r + 1; x r < m Aufgabe H8 (8+ Punkte) Gegeben sei folgendes Java-Programm P: ϕ (Vorbedingung) i = 0; res = 0; while (i < n){ i = i + 1; res = res + i * i * i; ψ (Nachbedingung) a) Als Vorbedingung ϕ für das oben aufgeführte Programm P gelte n 0 und als Nachbedingung ψ gelte res = ( n (n+1) ). Vervollständigen Sie die folgende Verifikation des Algorithmus, indem Sie die leeren Zeilen durch korrekte Zusicherungen entsprechend des Hoare-Kalküls 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. n 0 i = 0;

res = 0; while (i < n){ i = i + 1; res = res + i * i * i; res = ( n (n+1) ) 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. Es gilt ( x (x+1) ) + (x + 1) 3 = ( (x+1) (x+) ) für alle x R. b) Untersuchen Sie den Algorithmus P auf seine Terminierung. Für einen Beweis der Terminierung muss eine Variante angegeben werden und mit Hilfe des Hoare-Kalküls die Terminierung bewiesen werden.

Lösungsvorschlag a) n 0 n 0 0 = 0 0 = 0 i = 0; n 0 i = 0 0 = 0 res = 0; n 0 i = 0 res = 0 res = ( i (i+1) ) i n while (i < n){ res = ( i (i+1) ) i n i < n res + (i + 1) (i + 1) (i + 1) = ( (i+1) ((i+1)+1) ) (i + 1) n i = i + 1; res +i i i = ( i (i+1) ) i n res = res + i * i * i; res = ( i (i+1) ) i n Korrekturhinweise: res = ( i (i+1) ) i n (i < n) res = ( n (n+1) ) korrekte Anwendung der Zuweisungsregeln: jeweils 0,5 Punkte korrekte Anwendung der Schleifenregel (Schleifenbedingung bzw. ihre Negation kommt zu Beginn bzw. unmittelbar nach der Schleife hinzu und sonst ändert sich nichts): 1 Punkt korrekte Anwendung der Konsequenzregeln, sodass alle direkt untereinander stehenden Zusicherungen gefolgert werden können: insgesamt Punkte unmittelbar vor und am Ende der Schleife steht die gleiche nicht-leere Zusicherung: 1 Punkt an einer der beiden gerade genannten Stellen steht eine Schleifeninvariante: 1 Punkt an einer der beiden gerade genannten Stellen steht eine Zusicherung, aus der gemeinsam mit der negierten Schleifenbedingung die Nachbedingung folgt: 1 Punkt die entsprechenden Punkte gibt es nur, wenn an der jeweiligen Stelle keine sonstigen Fehler gemacht werden (beliebt: semantische Änderung ohne Konsequenzregel) es gibt keinen Punktabzug für eigentlich verbotene kleinere Änderungen wie: Tausch der Reihenfolge innerhalb einer Konjunktion Umwandlung von k 0 zu k < 0 Zusammenfassen von k 0 k > 0 zu k > 0 (die entsprechenden Fehler sollten aber kommentiert werden) wenn Fehler mehrfach gemacht werden, aber der eigentliche Lösungsweg richtig ist, wird nur beim ersten Fehler etwas abgezogen (Beispiel: semantische Änderung ohne Konsequenzregel)

b) Wir wählen als Variante V = n i. Hiermit lässt sich die Terminierung von P beweisen, denn für die einzige Schleife im Programm (mit Schleifenbedingung B = i < n) gilt: B V 0, denn B i < n n i > 0 V > 0 und n i = m i < n n (i + 1) < m i = i + 1; n i < m res = res + i * i * i; n i < m Korrekturhinweise: Angabe einer sinnvollen Variante: 0,5 Punkte Begründung, warum es sich um eine gültige Variante (V 0) handelt: 0,5 Punkte Beweis der Terminierung mittels des Hoare-Kalküls: 1 Punkt Aufgabe H9 (5+5 Punkte) 3 Erweitern sie die Klasses Set aus Aufgabe T7 indem sie zu der Klasse die Methoden intersection(set other) und union(set other) hinzufügen. Die Methode intersection(set other) soll ein Set zurückgeben was nur die Elemente enthält, die sowohl in der Menge sind worauf die Methode aufgerufen wurde, als auch in der Menge other. Die Methode union(set other) soll ein Set zurückgeben was alle Elemente aus der Menge worauf die Methode aufgerufen wuerde enthält, als auch die Element aus der Menge other. Dabei sollen die Attribute jeder Instanz der Klasse Set, wie davor, unveränderbar sein, nachdem sie im Konstruktor gesetzt wurden. Eine leere Menge kann dabei auch durch den Wert null representiert werden. Lösungsvorschlag class Set { private int value; private boolean present; private Set child; public Set (int value, boolean present) { this(value, present, null); private Set (int value, boolean present, Set child) { this.value = value; this.present = present; this.child = child; public Set add(int x) { return new Set(x, true, this); public Set remove(int x) { return new Set(x, false, this);

public boolean contains(int x) { if (this.value == x && this.present) { return true; else if (this.value == x &&!this.present) { return false; else if (this.child == null) { return false; else { return this.child.contains(x); public Set intersection(set other){ return this.intersection(this, other); public Set intersection(set topelement, Set other){ Set rest = null; if (this.child!= null){ rest = this.child.intersection(topelement, other); if (topelement.contains(this.value) && other.contains(this.value)){ return new Set(this.value, true, rest); else { return rest; public Set union(set other) { return union(this, other, other); private Set union(set left, Set right, Set topright) { if (right == null) { return left; Set res = left; if (right.child! = null) { res = union(left, right.child, topright); if (topright.contains(right.value)) { res.add(right.value); return res; 3 Bitte Quelltext für die Abgabe ausdrucken und zusätzlich per E-mail an den jeweiligen Tutor senden.