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 " + "<Vorname> <Nachname>"); 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 Stellig -keit Typ Kurzbeschreibung Ergebnis -typ abs 1 double Betrag double abs 1 float Betrag float abs 1 long Betrag long abs 1 int Betrag int acos 1 double Arcus Cosinus double asin 1 double Arcus Sinus double atan 1 double Arcus Tangens double ceil 1 double aufrunden double Oliver Haase Hochschule Konstanz 21
java.lang.math Name Stellig -keit Typ Kurzbeschreibung Ergebnis -typ cos 1 double Cosinus double exp 1 double e-funktion double floor 1 double abrunden double log 1 double Logarithmus, Basis e double max 2 double Maximum double max 2 float Maximum float max 2 long Maximum long max 2 int Maximum int min 2 double Minimum double Oliver Haase Hochschule Konstanz 22
java.lang.math Name Stellig -keit Typ Kurzbeschreibung Ergebnis -typ min 2 float Minimum float min 2 long Minimum long min 2 int Minimum int pow 2 double a hoch b double random 0 - Zufallszahl in [0;1] double round 1 double runden long sin 1 double Sinus double sqrt 1 double Quadratwurzel double tan 1 double Tangens double Oliver Haase Hochschule Konstanz 23
Time for a hot cup of java! Oliver Haase Hochschule Konstanz 24