MINT lernen

Abituraufgaben: Teile und herrsche

Den heißesten Tag der Woche finden und riesige Potenzen berechnen — zweimal hilft das Halbieren.

Dein Fortschritt:
0 / 0 Aufgaben
1

Die Wetterstation

14 BEAFB I–II

Eine Schul-Wetterstation speichert die Tageshöchsttemperaturen einer Woche in °C in der Reihung t. Um den heißesten Tag zu finden, wurde die abgebildete Methode groesster nach dem Prinzip Teile und herrsche programmiert. Der Aufruf lautet groesster(t, 0, t.length - 1).

Reihung t und Methode groesster
static int groesster(int[] a, int links, int rechts) {
    if (links == rechts) {
        return a[links];
    }
    int mitte = (links + rechts) / 2;
    int g1 = groesster(a, links, mitte);
    int g2 = groesster(a, mitte + 1, rechts);
    if (g1 >= g2) {
        return g1;
    }
    return g2;
}
  1. Beschreiben Sie am Beispiel der Methode groesster die drei Schritte der Strategie Teile und herrsche und nennen Sie den Basisfall. (3 BE)
  2. Stellen Sie die Aufrufe von groesster(t, 0, 5) als Aufrufbaum dar. Notieren Sie an jedem Aufruf die Parameter links, rechts und den Rückgabewert. (5 BE)
  3. Geben Sie die Anzahl der Aufrufe und die Anzahl der Vergleiche g1 >= g2 für diese Reihung an. Verallgemeinern Sie beide Anzahlen für eine Reihung mit \(n\) Elementen. (3 BE)
  4. Implementieren Sie nach demselben Prinzip eine Methode static int anzahlUeber(int[] a, int links, int rechts, int grenze), die zählt, an wie vielen Tagen die Temperatur über grenze lag. (3 BE)

Hinweise

Hinweis zu Aufgabe a)
Suchen Sie im Quelltext die Stelle, an der geteilt wird, die rekursiven Aufrufe und die Stelle, an der zwei Ergebnisse verbunden werden.
Hinweis zu Aufgabe b)
Der erste Aufruf teilt bei mitte = 2. Zeichnen Sie für jeden Aufruf zwei Kinder, bis die Bereiche nur noch ein Element haben.
Hinweis zu Aufgabe c)
Zählen Sie die Knoten Ihres Baums. Jeder Knoten mit zwei Kindern vergleicht genau einmal.
Hinweis zu Aufgabe d)
Der Basisfall liefert 1 oder 0; das Zusammenführen ist eine Addition.

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

Teilen: Der Bereich links … rechts wird bei mitte in zwei Hälften geteilt. Herrschen: Für beide Hälften wird groesster rekursiv aufgerufen (g1, g2). Zusammenführen: Der größere der beiden Teilwerte wird zurückgegeben. Basisfall: links == rechts — ein einzelnes Element ist sein eigenes Maximum.

Erwartungshorizont zu Aufgabe b)
groesster(0,5) → 22 ├─ groesster(0,2) → 22 │ ├─ groesster(0,1) → 14 │ │ ├─ groesster(0,0) → 14 │ │ └─ groesster(1,1) → 9 │ └─ groesster(2,2) → 22 └─ groesster(3,5) → 19 ├─ groesster(3,4) → 17 │ ├─ groesster(3,3) → 17 │ └─ groesster(4,4) → 6 └─ groesster(5,5) → 19

Der Rückgabewert 22 gehört zu Index 2 (dritter Tag).

Erwartungshorizont zu Aufgabe c)

11 Aufrufe, davon 6 Basisfälle und 5 Aufrufe mit Vergleich; also 5 Vergleiche. Allgemein: \(n\) Basisfälle und \(n - 1\) Zusammenführungen, insgesamt \(2n - 1\) Aufrufe und \(n - 1\) Vergleiche — genauso viele Vergleiche wie bei einer Schleife.

Erwartungshorizont zu Aufgabe d)
static int anzahlUeber(int[] a, int links, int rechts, int grenze) {
    if (links == rechts) {
        if (a[links] > grenze) {
            return 1;
        }
        return 0;
    }
    int mitte = (links + rechts) / 2;
    return anzahlUeber(a, links, mitte, grenze)
         + anzahlUeber(a, mitte + 1, rechts, grenze);
}

Für t und grenze = 15 liefert die Methode 3 (22, 17, 19).

2

Schnelles Potenzieren

16 BEAFB II–III

In der Kryptologie müssen Potenzen \(x^n\) mit sehr großen Exponenten berechnet werden. Die naive Methode multipliziert \(n - 1\)-mal mit \(x\). Die abgebildete Methode potenz nutzt dagegen \(x^n = x^{n/2}\cdot x^{n/2}\) für gerades \(n\) und \(x^n = x^{(n-1)/2}\cdot x^{(n-1)/2}\cdot x\) für ungerades \(n\).

Methode potenz
static long potenz(long x, int n) {
    if (n == 0) {
        return 1;
    }
    long h = potenz(x, n / 2);
    if (n % 2 == 0) {
        return h * h;
    }
    return h * h * x;
}
  1. Analysieren Sie den Aufruf potenz(3, 10): Geben Sie alle Aufrufe mit ihren Rückgabewerten in der Reihenfolge an, in der sie enden. (4 BE)
  2. Leiten Sie her, wie viele Multiplikationen potenz für \(n = 2^k\) höchstens ausführt, und vergleichen Sie für \(n = 1024\) mit dem naiven Verfahren. (4 BE)
  3. Erläutern Sie, warum die Variante return potenz(x, n / 2) * potenz(x, n / 2); (für gerades \(n\)) den Vorteil vollständig zunichtemacht. (4 BE)
  4. Beurteilen Sie den Einsatz von potenz für die Verschlüsselung, bei der Exponenten mit mehreren hundert Stellen vorkommen. Berücksichtigen Sie Laufzeit, Rekursionstiefe und den Datentyp long. (4 BE)

Hinweise

Hinweis zu Aufgabe a)
Der innerste Aufruf endet zuerst. Beginnen Sie bei n = 0.
Hinweis zu Aufgabe b)
Jeder Aufruf mit \(n > 0\) halbiert den Exponenten und multipliziert ein- oder zweimal.
Hinweis zu Aufgabe c)
Zählen Sie die Aufrufe, wenn in jedem Aufruf zwei rekursive Aufrufe stattfinden.
Hinweis zu Aufgabe d)
Wie viele Stellen hat \(\log_2 n\) für eine Zahl mit 300 Dezimalstellen? Wie groß darf ein long werden?

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

Aufrufkette: potenz(3,10) → potenz(3,5) → potenz(3,2) → potenz(3,1) → potenz(3,0). Sie enden in umgekehrter Reihenfolge:

Aufrufhn gerade?Rückgabe
potenz(3, 0)—Basisfall1
potenz(3, 1)1nein1 · 1 · 3 = 3
potenz(3, 2)3ja3 · 3 = 9
potenz(3, 5)9nein9 · 9 · 3 = 243
potenz(3, 10)243ja243 · 243 = 59 049
Erwartungshorizont zu Aufgabe b)

Für \(n = 2^k\) sind alle Exponenten außer 1 gerade: \(2^k, 2^{k-1}, \dots, 2\) mit je einer Multiplikation, dazu \(n = 1\) mit zwei Multiplikationen (\(h\cdot h\cdot x\)).

\(M(2^k) = k + 2 = \log_2 n + 2\); allgemein höchstens \(2(\lfloor\log_2 n\rfloor + 1)\). Für \(n = 1024\): 12 Multiplikationen statt 1023.

Erwartungshorizont zu Aufgabe c)

Beide Aufrufe berechnen dasselbe Ergebnis, aber jeweils vollständig neu. Die Zahl der Aufrufe verdoppelt sich auf jeder Ebene: \(1 + 2 + 4 + \dots + n \approx 2n\) Aufrufe. Damit ist der Aufwand wieder linear in \(n\) — schlechter als die naive Schleife, weil noch Methodenaufrufe hinzukommen. Der Vorteil entsteht nur, weil ein Teilproblem gelöst und das Ergebnis h doppelt verwendet wird.

Erwartungshorizont zu Aufgabe d)

Laufzeit: Die Zahl der Multiplikationen wächst nur mit \(\log_2 n\); bei 300 Dezimalstellen (\(n\approx10^{300}\approx2^{1000}\)) sind es etwa 2000 statt \(10^{300}\) Multiplikationen — nur so ist die Rechnung überhaupt möglich. Rekursionstiefe: etwa 1000 Aufrufe, unkritisch für den Aufrufstapel. Datentyp: Ein long reicht nur bis etwa \(9\cdot10^{18}\); die Ergebnisse laufen sofort über. Man muss deshalb nach jeder Multiplikation modulo rechnen und mit beliebig großen Zahlen (z. B. BigInteger) arbeiten. Fazit: Das Verfahren ist geeignet und wird in der Kryptologie so genutzt, aber nicht mit long.