OOP Aufgabenblatt 6

Werbung
1
Prof. Dr. Th. Letschert
OOP Aufgabenblatt 6
20. November 2013
Aufgabe 1
Informatiker, die nie eine (rekursive) Funktion zur Berechnung der Fibonacci–Zahlen oder der Fakultät geschrieben haben,
sind wie Enten, die nie im Wasser waren, oder Hunde die noch nie auf einem Knochen gekaut haben. – Arme Viecher
halt.
Eine solche bedauernswerte Kreatur wollen Sie nicht sein. Informieren Sie sich darum über die Fibonacci–Zahlen (Wikipedia) und wenn nötig auch über die Fakultätsfunktion. Schreiben Sie dann jeweils eine rekursive und eine iterative
Funktion zu deren Berechnung.
Löschen Sie Ihre Lösungen und versuchen es noch einmal ohne Abschreiben. Wenn das nicht geht, dann schreiben Sie
irgendwo ab. Wenn Sie eine funktionierende Lösung abgeschriebene Lösung haben, dann löschen Sie sie wieder und
versuchen es noch einmal ohne Abschreiben. Wiederholen Sie dieses Vorgehen so lange bis Sie in der Lage sich die
Fakultäts– und die Fibonacci–Funktion ohne jede Hilfe in iterativer und rekursiver Form korrekt zu implementieren. (Die
Verwendung von Arrays ist übrigens verboten!)
Aufgabe 2
1. Geben Sie für folgende rekursive Funktionen jeweils eine äquivalente iterative Funktion an.
public static int f1 (int n) {
try {
return f1 (n + Integer.parseInt(JOptionPane.showInputDialog("?")));
} catch (Exception e) {
return n;
}
}
public static int f2 () {
try {
return Integer.parseInt(JOptionPane.showInputDialog("?"));
} catch (Exception e) {
return f2();
}
}
public static int f3 () {
return f3_helfer(Integer.MIN_VALUE);
}
private static int f3_helfer (int n) {
try {
int m = Integer.parseInt(JOptionPane.showInputDialog("?"));
return (m>n) ? f3_helfer(m) : f3_helfer(n);
} catch (Exception e) {
return n;
}
}
2
2. Geben Sie für folgende rekursive Funktionen jeweils eine äquivalente iterative Funktion an. Ergänzen Sie dabei die
bedingte Anweisung am Anfang derart, dass alle Argumente, die zu einem Stackoverflow führen würden, mit einer
IllegalArgumentException abgewiesen werden.
public static int f1(int a, int b) {
if (....) throw new IllegalArgumentException();
if (a == b) {
return a;
} else {
return f1(a-1, b);
}
}
public static int f2(int a, int b) {
if (....) throw new IllegalArgumentException();
if (a == b) {
return a;
} else {
return f1(a--, b);
}
}
public static int f3(int a, int b) {
if (....) throw new IllegalArgumentException();
if (a == b) {
return a;
} else {
return f1(--a, b);
}
}
public static int f4(int n) {
if (....) throw new IllegalArgumentException();
if (n == 0) {
return 0;
} else {
return f1(n-1) + n;
}
}
public static int f5(int n) {
return f5_helfer(n, 0, 1);
}
private static int f5_helfer(int n, int m1, int m2) {
if (....) throw new IllegalArgumentException();
if (n <= 1) {
return m2;
} else {
return f5_helfer(n-1, m2, m1+m2);
}
}
Aufgabe 3
1. Definieren Sie rekursive Funktionen zur Addition und zur Multiplikation ganzer Zahlen. In diesen Funktionen dürfen nur Inkrement– und Dekrement–Operatoren (++ und --) verwendet werden, weitere arithmetische Operationen
sind verboten.
2. Wandeln Sie Ihre beiden Funktionen in iterative Form um.
3
Aufgabe 4
Eine Folge von natürlichen Zahlen sei definiert als:
a0 = 0
ai = 2 ∗ ai−1 + 1
1. Geben Sie die ersten 5 Glieder der Folge an!
2. Definieren Sie mit Stift auf Papier in mathematischer Notation eine rekursive Funktion f auf natürlichen Zahlen für
die gilt:
f (x) = ax
3. Schreiben Sie eine rekursive Java–Funktion f als statische Methode einer Klasse Folge im Paket folge, die f (x)
berechnet.
4. Geben Sie eine iterative Variante fIter von f an. In fIter soll f iterativ, d.h. durch eine Schleife berechnet
werden. Entwickeln Sie die Schleife mit der Tabellenmethode.
5. Geben Sie die Schleifeninvariante der Schleife in fIter in From eines Kommentars an. Die Funktion f kann dabei
verwendet werden.
6. Testen Sie fIter mit Hilfe von Junit-Test.
7. Formulieren Sie die Schleifeninvariante als assert–Anweisung.
8. Schreiben Sie eine Java–Funktion sumF als statische Methode der Klasse folge.Folge, die für eine natürliche
Zahl x den Wert
x
X
f (i)
i=0
mit Hilfe einer Schleife und fIter berechnet. (f und fIter wie oben.)
9. Geben Sie die Invariante der Schleife in sumF an.
10. Testen Sie sumF mit Hilfe von Junit-Test.
Aufgabe 5
Betrachten Sie folgende Funktion zur Berechnung der Summe einer Folge a1 + a2 + · · · an .
Mit vorgegebenem a1 und c. Das i-te Glied wird dabei wie folgt berechnet: ai = ai−1 + c:
public static int sumA(int n, int c, int a_1) {
int a = a_1;
int i = 1;
int s = a_1;
while (i < n) {
a = a + c;
s = s + a;
i = i + 1;
}
return s;
}
Die Hilfsvariable a ist überflüssig. Statt zuerst a zu erhöhen, um dann mit dessen neuem Wert von s zu erhöhen, kann s
sofort erhöht werden. Wie? Wie sieht die Schleife aus, die ohne die Hilfsvariable a auskommt?
4
Aufgabe 6
Ein Palindrom ist eine Zeichenkette die von rechts und links gelesen gleich ist. Beispielsweise ist Anna ein Palindrom.
(Groß-und Kleinschreibung ignorieren wir.)
Der Begriff Palindrom kann leicht rekursiv definiert werden: Ein Wort ist ein Palindom, wenn keinerlei Buchstaben
enthält, oder wenn der erste und der letzte Buchstabe gleich sind und die Zeichenkette dazwischen ein Palindrom ist.
Entwickeln Sie aus dieser Idee eine rekursive Funktion die Testet ob eine Zeichenkette ein Palindrom ist. Informieren Sie
sich bei der Java–API über die notwendigen Operationen auf Strings.
Schreiben Sie eine Benutzerschnittstelle als Klasse UI mit der die zu testenden Strings eingegeben werden können und
die den Palindrom–Test dann aktiviert.
Aufgabe 7
Der rekursive Palindrom-Test kann in eine iterative Form gebracht werden. Tun Sie das.
Herunterladen