Programmiertechnik Methoden, Teil 2 Prof. Dr. Oliver Haase
Oliver Haase
Hochschule Konstanz
1
Rekursion
Oliver Haase
Hochschule Konstanz
2
Definition Was ist Rekursion? Allgemein: Rekursion ist die Definition einer Sache durch sich selbst rekursive Definition In der Mathematik/Informatik: Definition einer Funktion f(n) durch sich selbst Wie funktioniert das? durch eine Fallunterscheidung bei der ‣ f(n) für einen Startwert (üblicherweise n = 0 oder 1) explizit definiert wird, z.B. f(1) = 5 ‣ f(n) für größere n auf f(m) mit m < n zurückgeführt wird, z.B. f(n) = f(n-1) +2 (auch f(n+1) = f(n) +2)
Oliver Haase
Hochschule Konstanz
3
Beispiel: Fakultät n! (sprich: „n Fakultät“) : Das Produkt der ersten n natürlichen Zahlen:
0! = 1 1! = 1 2! = 1 · 2 = 2 3! = 1 · 2 · 3 = 6 4! = 1 · 2 · 3 · 4 = 24 … n! = 1 · 2 · … · n
Die Fakultätsfunktion kann elegant rekursiv definiert werden:
Oliver Haase
Hochschule Konstanz
4
Fakultätsberechnung in Java public class Fakultaet { public static int fakultaet(int i) { if ( i == 0 ) { return 1; } return i * fakultaet(i -1); } public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.print("n: "); int n = scanner.nextInt();
}
}
System.out.println(n + "! = " + fakultaet(n));
Oliver Haase
Hochschule Konstanz
5
Beispiel: Fibonacci-Zahlen Fibonacci-Reihe: Beginnt mit 0 und 1, jede weitere Zahl ist die Summe der beiden vorhergehenden Zahlen: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, … Rekursive Definition der n-ten Fibonacci-Zahl:
Oliver Haase
Hochschule Konstanz
6
Fibonacci-Berechnung in Java public class Fibonacci { public static int fib(int i) { if ( i == 0 ) { return 0; } if ( i == 1 ) { return 1; } return fib(i -1) + fib(i -2); }
}
Mehrfachrekursion!
public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.print("n:"); int n = scanner.nextInt(); System.out.println("Fibonacci(" + n + ") = " + fib(n)); }
Oliver Haase
Hochschule Konstanz
7
Beispiel: Türme von Hanoi Kinderspiel mit drei Stäben und n verschieden großen Scheiben Zu Beginn liegen alle Scheiben geordnet auf dem linken Stab
Aufgabe: Bewege den Turm vom linken auf den rechten Stab unter Verwendung aller 3 Stäbe nur eine Scheibe pro Zug lege nie eine größere auf eine kleinere Scheibe
Oliver Haase
Hochschule Konstanz
8
Beispiel: Türme von Hanoi Wer wagt‘s?
Oliver Haase
Hochschule Konstanz
9
Beispiel: Türme von Hanoi Beobachtung: Aufgabe lässt sich gut rekursiv formulieren! Bewege Turm der Höhe n von start nach ziel, unter Verwendung von über: Turm der Höhe 1: bewege Scheibe von start nach ziel, fertig. Turm der Höhe n >1: bewege obere n -1 Scheiben von start nach über. bewege unterste Scheibe von start nach ziel. bewege obere n -1 Scheiben von über nach ziel.
Oliver Haase
Hochschule Konstanz
10
Türme von Hanoi in Java public class Hanoi { public static void bewegeTurm(int hoehe, int start, int ziel, int ueber) { if ( hoehe == 1 ) { System.out.println("bewege Scheibe von Stab " + start + " nach Stab " + ziel); } else { bewegeTurm(hoehe - 1, start, ueber, ziel); System.out.println("bewege Scheibe von Stab " + start + " nach Stab " + ziel); bewegeTurm(hoehe - 1, ueber, ziel, start); } } public static void main(String[] args) { java.util.Scanner scanner = new java.util.Scanner(System.in); System.out.println("Hoehe:"); int n = scanner.nextInt(); bewegeTurm(n, 1, 3, 2); } } // Hanoi Oliver Haase
Hochschule Konstanz
11
Diskussion Manche Probleme können elegant rekursiv gelöst werden. Rekursion ist im allgemeinen langsamer als Iteration (Methodenaufruf kostet Rechenzeit) Ohne Abbruchbedingung führt Rekursion zu Endlosberechnung! Vorsicht bei Mehrfachrekursion: Dahinter verbirgt sich eine Aufwandexplosion!
fib(2) 2 rekursive Aufrufe fib(3) 4 rekursive Aufrufe fib(4) 8 rekursive Aufrufe fib(5) 14 rekursive Aufrufe fib(6) 24 rekursive Aufrufe … fib(60) 5 009 461 563 920 rekursive Aufrufe
Oliver Haase
Hochschule Konstanz
12
main-Methode
Oliver Haase
Hochschule Konstanz
13
Eingabeparameter Syntaxregel public static void main(String[] args) { … }
Was hat es mit dem formalen Parameter args auf sich?
Er dient dazu, dem Programm beim Start Parameter mitzugeben, die dann in der main-Methode verfügbar sind!
Oliver Haase
Hochschule Konstanz
14
Beispiel public class GrussWort { public static void main(String[] args) { System.out.println("Hallo, " + args[0] + "!"); System.out.println(args[1] + " ist aber ein schoener Nachname :-)"); } }
Konsole
Programmaufruf
java Grusswort Manfred Mustermann Hallo, Manfred! Mustermann ist aber ein schoener Nachname :-) args enthält die Kommandozeilen-Parameter in der richtigen Reihenfolge, args[0], args[1], … Oliver Haase
Hochschule Konstanz
15
Beispiel Vorsicht, falscher Aufruf (weniger als 2 Parameter) führt zu Programmabsturz! Konsole java Grusswort java.lang.ArrayIndexOutOfBoundsException: 0 at Grusswort.main(Grusswort.java:3) Mehr als 2 Parameter sind problemlos – überflüssige Parameter werden einfach ignoriert: Konsole java Grusswort Rainer Maria Rilke Hallo, Rainer! Maria ist aber ein schoener Nachname :-)
Oliver Haase
Hochschule Konstanz
16
Parameter-Kontrolle Die richtige Anzahl von Parametern sollte in der main-Methode überprüft werden: public class GrussWort2 { public static void main(String[] args) { if ( args.length != 2 ) { System.out.println("Benutzung: java Grusswort " + " "); } else { System.out.println("Hallo, " + args[0] + "!"); System.out.println(args[1] + " ist aber ein schoener Nachname :-)"); } } }
Oliver Haase
Hochschule Konstanz
17
args-Konvertierung Die Eingabeargumente sind immer Zeichenketten Was tun, wenn bspw. eine Ganzzahl eingeben werden soll?
String in Ganzzahl/Gleitpunktzahl/etc. konvertieren Beispiele: int number = Integer.parseInt(args[1]); double fraction = Double.parseDouble(args[0]); boolean flag = Boolean.parseBoolean(args[2]);
Oliver Haase
Hochschule Konstanz
18
Klassenmethoden aus anderen Klassen aufrufen
Oliver Haase
Hochschule Konstanz
19
Motivation Bisher haben wir (Klassen-)Methoden nur innerhalb der Klasse verwendet, in der sie definiert wurden. Eine Klassenmethode kann aber auch von einer anderen Klasse unter Voranstellung des Klassennamens aufgerufen werden. Beispiel: public class TesteFakultaet { public static void main(String[] args) { int n = Fakultaet.fakultaet(5); } }
Oliver Haase
Hochschule Konstanz
20
java.lang.Math Die Klasse java.lang.Math enthält eine Reihe von mathematischen Funktionen als Klassenmethoden.
Name abs abs abs abs acos asin atan ceil Oliver Haase
Stellig -keit 1 1 1 1 1 1 1 1
Typ
Kurzbeschreibung
double float long int double double double double
Betrag Betrag Betrag Betrag Arcus Cosinus Arcus Sinus Arcus Tangens aufrunden Hochschule Konstanz
Ergebnis -typ double float long int double double double double 21
java.lang.Math Name cos exp floor log max max max max min
Oliver Haase
Stellig -keit 1 1 1 1 2 2 2 2 2
Typ
Kurzbeschreibung
double double double double double float long int double
Cosinus e-Funktion abrunden Logarithmus, Basis e Maximum Maximum Maximum Maximum Minimum
Hochschule Konstanz
Ergebnis -typ double double double double double float long int double
22
java.lang.Math Name min min min pow random round sin sqrt tan
Oliver Haase
Stellig -keit 2 2 2 2 0 1 1 1 1
Typ
Kurzbeschreibung
float long int double double double double double
Minimum Minimum Minimum a hoch b Zufallszahl in [0;1] runden Sinus Quadratwurzel Tangens
Hochschule Konstanz
Ergebnis -typ float long int double double long double double double
23
Time for a hot cup of java!
Oliver Haase
Hochschule Konstanz
24