MINT lernen

Übungen: Rekursive Methoden entwerfen

Zehn Übungen zum Entwerfen rekursiver Methoden — vom Rezept bis zum Hilfsparameter.

Dein Fortschritt:
0 / 0 Aufgaben
1

Übungsaufgaben

Zehn Übungen zum Klicken, Zuordnen, Rechnen und Knobeln — von AFB I bis AFB III. Jede Übung gibt dir sofort Rückmeldung; wenn du nicht weiterkommst, helfen die gestuften Tipps.

A1
Das Rezept in der richtigen Reihenfolge
AFB I

Gib die Schritte beim Entwurf einer rekursiven Methode in der richtigen Reihenfolge an.

Ziehe die Karten in die richtige Reihenfolge — mit der Tastatur: ↑/↓ verschiebt, Shift+↑/↓ wechselt nur den Fokus.
1Festlegen, was die Methode für eine Eingabe liefern soll
2Das Problem durch ein kleineres Problem derselben Art ausdrücken
3Den einfachsten Fall bestimmen, der ohne Selbstaufruf lösbar ist
4Den Rekursionsschritt formulieren: Teilergebnis verwenden und verknüpfen
5Terminierung begründen und mit Beispielen testen
Wer ohne klare Festlegung anfängt, weiß nicht, was der Selbstaufruf liefert — dann kann man ihm auch nicht „vertrauen“. Geprüft wird am Schluss.
Ansatz: Was muss feststehen, bevor man sich auf das Ergebnis eines Selbstaufrufs verlassen kann?
Weiter: Die Probe kommt immer zuletzt.
A2
Der passende einfachste Fall
AFB I

Ordne jedem Problem die Abbruchbedingung zu, die zu einer naheliegenden rekursiven Lösung passt.

Ziehe jede Karte in den passenden Korb — oder wähle sie mit Enter aus und drücke dann die Ziffer des Korbs (0 legt sie zurück).
1n == 0
2n < 10
3s.length() == 0
4i == a.length
Der einfachste Fall hängt davon ab, was schrumpft: eine Zahl bis 0, Ziffern bis zur einstelligen Zahl, ein Text bis zur leeren Zeichenkette, ein Index bis zum Ende der Reihung.
Ansatz: Überlege zuerst: Was wird bei jedem Schritt kleiner — eine Zahl, die Anzahl der Ziffern, ein Text oder der Rest einer Reihung?
Weiter: Bei Ziffern ist die einstellige Zahl der einfachste Fall.
A3
Zerlegungen der Potenz
AFB I

Gesucht ist eine rekursive Methode für \(b^e\) mit \(e \ge 0\). Nenne alle Aussagen, die als Abbruchbedingung oder Zerlegung korrekt sind.

Mehrere Antworten sind richtig. Markiere alle zutreffenden und klicke dann auf „Auswahl prüfen“.
Zwei verschiedene Zerlegungen führen zum Ziel: Die erste verkleinert e um 1 (e Aufrufe), die zweite halbiert e — das braucht nur etwa log₂ e Aufrufe und ist die Idee der schnellen Potenz.
Ansatz: Setze Zahlen ein, z. B. \(b = 2\), \(e = 4\).
Weiter: Die Halbierung funktioniert nur, wenn e gerade ist.
A4
Ziffernprodukt
AFB II

Wende die Methode ziffernProdukt auf verschiedene Zahlen an.

static int ziffernProdukt(int n) {
    if (n < 10) return n;
    return n % 10 * ziffernProdukt(n / 10);
}
Arbeite die Kette Schritt für Schritt ab: Erst wenn ein Schritt stimmt, wird der nächste freigeschaltet. Enter prüft.
  1. ziffernProdukt(234) =
  2. ziffernProdukt(5) =
  3. ziffernProdukt(1203) =
  4. Aufrufe bei ziffernProdukt(98765): Aufrufe
234: 4 · 3 · 2 = 24. Enthält die Zahl eine 0, ist das Produkt 0 — die Rekursion läuft trotzdem bis zur ersten Ziffer weiter. Die Zahl der Aufrufe ist die Zahl der Ziffern.
Ansatz: Wie bei der Quersumme: letzte Ziffer mit % 10, Rest mit / 10.
Weiter: Eine einstellige Zahl wird unverändert zurückgegeben.
A5
Problem und Rekursionsschritt
AFB II Mix

Bestimme zu jedem Problem den passenden Rekursionsschritt.

Ansatz: Suche zuerst die Schritte mit a[i] — sie gehören zu Reihungen.
Weiter: Bei Text wird verkettet, bei Zahlen gerechnet.
A6
Vorkommen zählen
AFB II

Die Methode soll zählen, wie oft x in a ab Index i vorkommt. Überprüfe sie.

In diesem Quelltext stecken Fehler. Klicke genau die falschen Zeilen an — die richtigen musst du stehen lassen.
Zwei typische Entwurfsfehler: ein falscher Wert im einfachsten Fall (jedes Ergebnis wäre um 1 zu groß) und ein Selbstaufruf, der das Problem nicht verkleinert.
Ansatz: Prüfe mit der leeren Reihung: Was müsste herauskommen?
Weiter: Wird das Restproblem bei jedem Aufruf kleiner?
A7
Minimum mit Startmethode
AFB II

Erstelle aus den Bausteinen eine Startmethode minimum(a) und eine rekursive Hilfsmethode minimum(a, i) für nicht leere Reihungen.

Setze den Bauplan von oben nach unten zusammen. Ein Klick legt den Baustein auf den nächsten freien Platz, ein Klick im Bauplan legt ihn zurück. Enter funktioniert genauso.
Die Startmethode versteckt den Hilfsparameter. Mit i == a.length griffe a[i] hinter das Ende (ArrayIndexOutOfBoundsException), mit minimum(a, i) endete die Rekursion nie.
Ansatz: Die Startmethode kommt zuerst und besteht aus einer einzigen Anweisung.
Weiter: Beim letzten Index ist nur noch ein Element übrig.
A8
Ist die Reihung aufsteigend sortiert?
AFB III

Entwirf Schritt für Schritt eine rekursive Methode istAufsteigend(a, i).

Spiele den Ablauf Schritt für Schritt durch: Was passiert als Nächstes? Nur die richtige Karte bringt dich weiter.
    Boolesche Rekursion verknüpft mit && bzw. ||. Der Kurzschluss von && sorgt dafür, dass beim ersten Fehler sofort abgebrochen wird.
    Ansatz: Lege zuerst fest, was die Methode für ein bestimmtes i liefert.
    Weiter: Sortiert heißt: jedes Nachbarpaar stimmt.
    A9
    Verschachtelter Selbstaufruf
    AFB III Trick

    Untersuche die Methode f: Welchen Wert liefert f(9875)?

    static int f(int n) {
        if (n < 10) return n;
        return f(n % 10 + f(n / 10));
    }
    Überlege selbst und trage das Ergebnis ein — Enter prüft direkt.
    Der innere Aufruf f(n / 10) steckt im Parameter des äußeren. f(98) = f(8 + f(9)) = f(17) = f(7 + 1) = 8, f(987) = f(7 + 8) = f(15) = 6, f(9875) = f(5 + 6) = f(11) = 2. Die Methode bildet so lange Quersummen, bis eine Ziffer übrig bleibt (9 + 8 + 7 + 5 = 29 → 11 → 2). Wer 29 antwortet, hat nur die erste Quersumme gebildet.
    Ansatz: Werte von innen nach außen aus und beginne mit kleinen Zahlen: f(98).
    Weiter: Das Ergebnis ist immer einstellig.
    A10
    Teiler zählen
    AFB III

    anzahlTeiler(n, t) soll die Teiler von n zählen, die mindestens t groß sind; gestartet wird so, dass alle Teiler gezählt werden. Implementiere die Methode, indem du die Lücken füllst.

    Wähle in jedem Menü den passenden Eintrag und prüfe dann alle auf einmal.
    static int anzahlTeiler(int n, int t) {
        if (t > n) return ;
        if (n % t == 0) return ;
        return ;
    }
    // Start: anzahlTeiler(12, )  liefert 6
    Der Hilfsparameter t läuft von 1 bis n; danach ist nichts mehr zu zählen. Mit dem Start bei 0 gäbe n % 0 eine ArithmeticException, mit 2 fehlte der Teiler 1. Die Rekursionstiefe ist n + 1 — für große n wäre eine Schleife besser.
    Ansatz: Wann ist nichts mehr zu zählen?
    Weiter: Nur bei einem Teiler wird 1 addiert; in beiden Fällen geht es mit t + 1 weiter.