MINT lernen

Abituraufgaben: Rekursion und Iteration

Zwei Aufgaben im Abiturformat — von Messreihen bis zu Routen durch den Stadtplan.

Dein Fortschritt:
0 / 0 Aufgaben
1

Messwerte über der Grenze

AFB I–II

Eine Wetterstation speichert Tageshöchstwerte der Temperatur in °C in einer Reihung werte. Ein Programm zählt, an wie vielen Tagen eine Grenze überschritten wurde. Es verwendet die abgebildete Methode, die mit zaehleUeber(werte, grenze, 0) aufgerufen wird.

Material: rekursive Methode
static int zaehleUeber(int[] werte, int grenze, int i) {
    if (i == werte.length) {
        return 0;
    }
    int rest = zaehleUeber(werte, grenze, i + 1);
    if (werte[i] > grenze) {
        return rest + 1;
    }
    return rest;
}
  1. Beschreiben Sie, wie die Methode das Ergebnis ermittelt. Gehen Sie dabei auf Abbruchbedingung und Rekursionsschritt ein. 3 BE
  2. Wenden Sie die Methode auf werte = {12, 31, 27, 8, 35} und grenze = 25 an. Stellen Sie die Aufrufe in einer Tabelle mit i, werte[i], rest und Rückgabewert dar. 5 BE
  3. Implementieren Sie eine gleichwertige Methode zaehleUeber(int[] werte, int grenze) ohne Selbstaufruf. 4 BE
  4. Erläutern Sie, warum für eine Messreihe über 300 Jahre (etwa 110 000 Werte) die iterative Fassung vorzuziehen ist. 3 BE

Insgesamt 15 BE

Hinweise

Hinweis zu Aufgabe a)
Welcher Wert entsteht für den leeren Rest der Reihung? Wann wird zum Ergebnis des Restes 1 addiert?
Hinweis zu Aufgabe b)
Die Aufrufe laufen mit i = 0 bis i = 5; die Rückgabewerte entstehen von hinten nach vorn.
Hinweis zu Aufgabe c)
Die Abbruchbedingung liefert den Startwert der Zählvariablen.
Hinweis zu Aufgabe d)
Wie viele Rahmen liegen bei der rekursiven Fassung gleichzeitig auf dem Stapel?

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

Abbruchbedingung: Ist i gleich der Länge, ist kein Wert mehr übrig — Rückgabe 0. Rekursionsschritt: Die Methode zählt zuerst rekursiv die Überschreitungen ab i + 1 (rest) und addiert 1, falls werte[i] über der Grenze liegt. Ergebnis ist die Zahl der Werte ab Index i, die größer als grenze sind; beim Start mit 0 also in der ganzen Reihung.

Erwartungshorizont zu Aufgabe b)
iwerte[i]restwerte[i] > 25Rückgabe
5———0 (Abbruch)
4350wahr1
381falsch1
2271wahr2
1312wahr3
0123falsch3

Die Tabelle ist in der Reihenfolge der Rückgaben notiert; aufgerufen wird in der Reihenfolge i = 0, 1, …, 5. Ergebnis 3.

Erwartungshorizont zu Aufgabe c)
static int zaehleUeber(int[] werte, int grenze) {
    int anzahl = 0;
    for (int i = 0; i < werte.length; i++) {
        if (werte[i] > grenze) {
            anzahl++;
        }
    }
    return anzahl;
}
Erwartungshorizont zu Aufgabe d)

Die rekursive Fassung legt für jeden Index einen Rahmen an, bei 110 000 Werten also rund 110 000 gleichzeitig offene Aufrufe. Der Aufrufstapel von Java reicht typischerweise nur für einige tausend bis zehntausend Ebenen, es droht ein StackOverflowError. Die Schleife braucht unabhängig von der Länge nur einen Rahmen und ist außerdem etwas schneller, da kein Aufruf verwaltet werden muss. Beide haben dieselbe Zahl von Vergleichen.

2

Wege durch den Stadtplan

AFB II–III

In einer Stadt mit schachbrettartigen Straßen will ein Kurierdienst von der Kreuzung (0 | 0) zur Kreuzung (x | y) fahren und dabei nur nach Osten oder Norden abbiegen. Die Methode wege berechnet die Anzahl der möglichen Routen.

Material: Methode wege
static long wege(int x, int y) {
    if (x == 0 || y == 0) {
        return 1;
    }
    return wege(x - 1, y) + wege(x, y - 1);
}
  1. Bestimmen Sie wege(2, 2) und die Anzahl der dabei entstehenden Aufrufe von wege. 4 BE
  2. Analysieren Sie, welche Aufrufe bei wege(2, 2) mehrfach vorkommen, und schätzen Sie ab, welche Folgen das für wege(16, 16) mit dem Ergebnis 601 080 390 hat. 4 BE
  3. Entwickeln Sie eine Methode wegeTabelle(int x, int y), die ohne Selbstaufruf auskommt und die Zwischenergebnisse in einer zweidimensionalen Reihung speichert. 6 BE
  4. Beurteilen Sie beide Methoden hinsichtlich Laufzeit und Speicherbedarf. 4 BE

Insgesamt 18 BE

Hinweise

Hinweis zu Aufgabe a)
Zeichnen Sie den Aufrufbaum. Jeder Aufruf mit x, y ≥ 1 hat zwei Kinder.
Hinweis zu Aufgabe b)
Die Blätter des Aufrufbaums liefern jeweils 1. Wie viele Blätter braucht es für das Ergebnis 601 080 390?
Hinweis zu Aufgabe c)
Füllen Sie die Tabelle zeilenweise; t[i][j] hängt nur von Werten links und darunter ab (Kapitel 2, zweidimensionale Reihungen).
Hinweis zu Aufgabe d)
Vergleichen Sie die Zahl der Aufrufe mit der Zahl der Tabellenfelder und die Rekursionstiefe mit der Größe der Tabelle.

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

\(\text{wege}(2,2) = \text{wege}(1,2) + \text{wege}(2,1)\) mit \(\text{wege}(1,2) = \text{wege}(0,2) + \text{wege}(1,1) = 1 + 2 = 3\) und ebenso \(\text{wege}(2,1) = 3\): Ergebnis 6.

Aufrufe: \(C(1,1) = 3\), \(C(1,2) = C(2,1) = 1 + C(1,1) + 1 = 5\), \(C(2,2) = 1 + 5 + 5 = 11\).

Erwartungshorizont zu Aufgabe b)

wege(1, 1) wird zweimal berechnet (von wege(1, 2) und von wege(2, 1) aus), die Randaufrufe wie wege(0, 1) ebenfalls mehrfach. Da nur die Blätter den Wert 1 liefern und alles andere Summen sind, braucht das Ergebnis 601 080 390 genauso viele Blätter; der Aufrufbaum ist ein vollständiger Binärbaum mit rund \(2 \cdot 601\,080\,390 - 1 \approx 1{,}2\) Milliarden Aufrufen. Das dauert selbst auf schnellen Rechnern Sekunden, und schon wenige Kreuzungen mehr vervielfachen die Zeit.

Erwartungshorizont zu Aufgabe c)
static long wegeTabelle(int x, int y) {
    long[][] t = new long[x + 1][y + 1];
    for (int i = 0; i <= x; i++) {
        for (int j = 0; j <= y; j++) {
            if (i == 0 || j == 0) {
                t[i][j] = 1;
            } else {
                t[i][j] = t[i - 1][j] + t[i][j - 1];
            }
        }
    }
    return t[x][y];
}

wegeTabelle(2, 2) liefert 6, wegeTabelle(16, 16) liefert 601 080 390 nach nur 289 Tabellenfeldern.

Erwartungshorizont zu Aufgabe d)

Laufzeit: wege braucht etwa doppelt so viele Aufrufe, wie es Routen gibt — das wächst exponentiell mit x + y. wegeTabelle berechnet jedes Feld genau einmal: \((x+1)(y+1)\) Schritte. Speicher: wege hat höchstens \(x + y + 1\) Rahmen gleichzeitig auf dem Stapel, wegeTabelle braucht eine Tabelle mit \((x+1)(y+1)\) Feldern. Der zusätzliche Speicher ist klein, der Zeitgewinn gewaltig; für praktische Größen ist die Tabelle klar vorzuziehen. Die rekursive Methode bleibt als lesbare Beschreibung des Zusammenhangs wertvoll.