Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Praktische Informatik 1
Prof. Dr. H. Schlingloff
2
6.4 Rekursion und Iteration, Kellerprinzip
Beispiel Fibonacci-Funktion: static int fibRek1(int x) { return (x<=1) ? 1 : fibRek1(x-1) + fibRek1(x-2) ; } static int fibRek2(int x) { if (x<=1) return 1 ; else return fibRek2 (x-1) + fibRek2 (x-2) ; Hohe Aufrufkomplexität!
3
Iterative Fassung? 1 2 3 4 5 6 8 13 fib: Parallele Zuweisung
1 2 3 4 5 6 8 13 fib: Parallele Zuweisung (ergebnis, voriges) = (ergebnis + voriges, ergebnis) in Java so nicht möglich! ergebnis voriges
4
Iterative Fassung static int fibIter(int x) {
int ergebnis = 1, voriges = 1; int merker; while (x > 1) { merker = ergebnis + voriges; voriges = ergebnis; ergebnis = merker; x--; }; return ergebnis; }
5
Ausführung Zeit x 8 7 6 5 4 3 2 1 ergebnis 13 21 34 voriges merker -
while (x > 1) { merker = ergebnis + voriges; voriges = ergebnis; ergebnis = merker; x--; }
6
Allgemeines Prinzip? Im Beispiel funktioniert der „Trick“, weil nur die letzten beiden Zwischenergebnisse gebraucht werden Im allgemeinen sind nach Beendigung eines rekursiven Aufrufs noch alle vorherigen Zwischenergebnisse nötig. Beispiel: static String reverse (String s) { return (s.length() == 1 ? s : reverse(s.substring(1))+s.substring(0,1)); }
7
Aufrufkeller reverse ("ABCD") = reverse ("BCD") + "A"
| reverse ("BCD") = reverse ("CD") + "B" | | reverse ("CD") = reverse ("D") + "C" | | | reverse ("D") = "D" | | reverse ("CD") = "D" + "C" = "DC" | reverse ("BCD") = "DC" + "B" = "DCB" reverse ("ABCD") = "DCB" + "A" = "DCBA"
8
allgemeine Lösung mit Keller
import java.util.Stack; static Stack myStack = new Stack(); static String reverseIt (String s) { while(s.length() != 1) { myStack.push(s.substring(0,1)); s = s.substring(1); }; while(! myStack.empty()) { s = s + myStack.pop(); } return(s);
9
Entrekursivierungs-Schema
Allgemein: rek(x) = b(x)? e(x): f( x, rek( g(x) )) wird zu while (!b(x)) { stack.push(x); x = g(x); } x = e(x); while (!stack.empty()) { x = f ( stack.pop(), x);} return x; Übung: mehrere rekursive Aufrufe (z.B. fib)
10
Kapitel 7: Objektorientierung
7.1 Abstrakte Datentypen 7.2 Klassen und Objekte 7.3 Vererbung, Polymorphie, Sichtbarkeit und Bindungsregeln 7.4 Parallelität, Threads, Ausnahmebehandlung 7.5 Klassenvariablen, Klassenmethoden, abstrakte Klassen
11
7.1 Abstrakte Datentypen abstrakte Datentypen (ADT): Konzept aus der theoretischen Informatik Signatur = (Grundmenge, Menge von Operationen und Stelligkeiten) Beispiel: (N0,0,s,+,*): Welche Datenobjekte vom Typ N0 gibt es (mindestens)? 0 : N0 s : N0 N0 +: N0×N0 N0 *: N0×N0 N0
12
Termalgebra alle Objekte, die sich als Ergebnis wohlgeformter Terme auf Grund der Signatur darstellen lassen: 0, s(0), s(s(0)), s(s(s(0))), … 0+0, (0+0)+0, … s(0)+s(0), s(s(0))+s(s(s(0))), … s(s(0))*(s(s(0))*(s(s(0)))), (0*s(0))+s(0), … Die Objekte, die sich so darstellen lassen, nennt man die Termalgebra der Signatur
13
Äquivalenzklassen Nicht alle Terme geben verschiedene Werte: z.B ist s(0)+s(0) gleich zu s(s(0)) (manchmal ist 1+1=2) Äquivalenzklassenbildung durch Angabe von (allgemeingültigen) Gesetzen: x+0=x x+s(y)=s(x+y) x*0=0 x*s(y)=x+(x*y) Damit lässt sich obige Aussage beweisen
14
Beweise 1+1=2 s(0)+s(0) =? s(s(0)) x+0=x x+s(y)=s(x+y) x*0=0
x*s(y)=x+(x*y) s(0)+s(0) =? s(s(0))
15
Definition abstrakter Datentyp
ADT=(Signatur, Gesetze) Wenn die Gesetze ausschließlich aus Gleichungen bestehen, spricht man auch von einer Varietät (engl.: variety) Im Allgemeinen lässt man auch Bedingungen und Ungleichungen zu Die Gesetze beschreiben, was für alle Objekte dieses Typs gelten soll. Beispiel: ADT IntSet „Menge ganzer Zahlen“ Signatur: (IntSet, , , , , , –) : IntSet : IntSet × IntSet IntSet : Z × IntSet boolean Gesetze: z.B. x y = y x x = …
16
Die Gesetze legen fest, was für alle Instanzen gelten soll
Konkrete Mengen ganzer Zahlen (z.B. {1,2,3} oder {x | x%2=0} sind Instanzen des abstrakten Typs Die Gesetze legen fest, was für alle Instanzen gelten soll Beispiel: {1,2,3} {4,5} = {4,5} {1,2,3} {x | x%2=0} =
17
Tupel Beispiel: Paare ganzer Zahlen ZZ:
ADT ZZ = (ZZ, first, second, conc) first, second : ZZ Z conc : Z Z ZZ Gesetze: first(conc(x,y))=x second(conc(x,y))=y Instanzen: 3,-5, 0,0, -12,12, … first(3,0)=3 conc(1,2)=1,2
18
Sequenzen seq : (seq,empty,isEmpty,…):
(parametrisiert mit Basistyp ) empty : seq isEmpty : seq boolean prefix: × seq sequ first: seq rest: seq seq postfix: seq × seq last: seq lead: seq seq isEmpty(empty) = true isEmpty(prefix(a,x)) = false isEmpty(postfix(x,a)) = false first(prefix(a,x))= a rest(prefix(a,x))= x last(postfix(x,a))= a lead(postfix(x,a))= x
19
first rest postfix prefix lead last
20
Eigenschaften first(rest(prefix(a, prefix(b, empty)))) = b
rest(rest(prefix(a, prefix(b, empty)))) = empty last(lead(postfix(a, postfix(b,empty)))) = b … prefix(a,empty) =? postfix(empty,a)
21
Typerweiterung abgeleitete Operation +: rekursive Definitionen von +:
+: seq seq prefix(a,x)=a+x postfix(x,a)=x+a x+empty=x empty+x=x x+(y+z)=(x+y)+z rekursive Definitionen von +: x+empty=x x+postfix(y,a) = postfix(x+y,a) empty+x=x prefix(a,x)+y = prefix(a,x+y)
22
Stapel und Schlangen Stapel („stack“): einseitiger Zugriff
empty, isEmpty, first, rest, prefix – oder – empty, isEmpty, last, lead, postfix top first/last, pop rest/lead, push prefix/postfix Schlange („queue“): empty, isEmpty, first, rest, postfix – oder – empty, isEmpty, last, lead, prefix head first/last, tail rest/lead, append postfix/prefix „enqueue“ push pop append top tail „dequeue“ head
23
Multimengen bag : empty : bag isEmpty : bag boolean
insert: bag × bag delete: bag × bag elem: × bag boolean any: bag bag : isEmpty(empty) = true isEmpty(insert(x,a)) = false insert(insert(x,a),b)= insert(insert(x.b),a) delete(empty,a) = empty delete(insert(x,a),a) = x delete(insert(x,b),a) = insert(delete(x,a),b) elem(a, empty) = false elem(a, insert(x,a)) = true elem(a,insert(x,b) = elem(a,x) (a≠b) elem(any(x),x) = true (x≠empty)
24
Beispiel-Algorithmus für Multimengen
card: bag × N0 int card (bag x, b){ if (isEmpty(x)) return 0; else { b = any(x); return card(delete(x,b),a) + ((a=b)?1:0); }
25
7.2 Klassen und Objekte Klasse = Zustandsvariablen + Methoden
Eine Klasse ist die Java-Realisierung eines abstrakten Datentyps. In der objektorientierten Programmierung sind Klassen das grundlegende Strukturierungsmittel. Zustandsvariablen sind nichtstatische Datenfelder Methoden sind Funktionen bzw. Operationen zur Erzeugung und Verarbeitung von Objekten der Klasse (Aktionen, die ausgeführt werden können) Klasse = Zustandsvariablen + Methoden
26
Klassen Beispiel: Philosophen sitzen um einen Tisch, denken, werden hungrig und essen: class Philosoph { boolean hungrig; void denken() {…}; void essen() {…}; } Klassen bestehen also im Wesentlichen aus der Deklaration von Daten- und Funktionsteilen (vgl. Turing/von-Neumann Analogie zwischen Daten und Programmen) Datenfelder bestimmen durch ihren aktuellen Wert während einer Berechnung den Zustand der abgeleiteten Objekte Methoden bestimmen die Aktionsmöglichkeiten der Objekte
27
Objekte Objekte sind Instanzen von Klassen
(das Objekt `Sokrates´ ist eine Instanz der Klasse `Philosoph´, kann `hungrig´ sein oder nicht und beherrscht die Methode `denken´ mit Ergebnistyp `void´) Objekte können von anderen Objekten erzeugt und aufgerufen werden public static void main(String[] args) { Philosoph sokrates = new Philosoph(); sokrates.denken(); if(sokrates.hungrig) sokrates.essen; System.out.println(sokrates.hungrig); }
28
Objektorientierte Modellierung
Klassen modellieren ein Konzept eines Anwendungsbereiches oder eine Gemeinsamkeit mehrerer Dinge (platonische „Idee“) Objekte modellieren die konkreten Akteure oder Gegenstände des betrachteten Bereiches Berechnungen entstehen dadurch, dass Objekte miteinander und mit dem Benutzer kommunizieren sich gegenseitig aufrufen Nachrichten austauschen neue Objekte erzeugen Wurzel der Interaktion: public class Main mit Methode public static void main(String[] args) {…}
Ähnliche Präsentationen
© 2024 SlidePlayer.org Inc.
All rights reserved.