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