Algorithmen
Algorithmen entwerfen: vom Problem zum Struktogramm
Schrittweise Verfeinerung, Struktogramme und der Nachweis, dass ein Entwurf wirklich das Richtige tut.
Benötigte Grundlagen
Dieses Vorwissen brauchst du für das Kapitel. Schau kurz nach, wenn dir etwas davon nicht mehr präsent ist, sonst leg direkt los.
Einführung
„Schreibe ein Programm, das die Klassenarbeit auswertet.“ So lautet die Aufgabe. Und jetzt?
Der häufigste Anfängerfehler an dieser Stelle ist, sofort zu tippen. Man kommt ein Stück weit, merkt dann, dass etwas fehlt, baut um, merkt wieder etwas, und nach zwei Stunden ist der Quelltext ein Flickwerk, das man selbst nicht mehr versteht.
Es gibt ein Verfahren, das genau das verhindert, und es kommt ohne Rechner aus. Man zerlegt das große Problem so lange in kleinere, bis jedes Stück offensichtlich lösbar ist. Das dauert am Anfang länger und am Ende deutlich kürzer.
Das kannst du nach diesem Kapitel
die schrittweise Verfeinerung anwenden und ein Problem in bearbeitbare Teilschritte zerlegen.
einen als darstellen und aus einem Struktogramm Pseudocode ableiten.
den Ablaufsinn eines Entwurfs an Beispielwerten prüfen.
mit einer Invariante begründen, dass ein Algorithmus das Richtige berechnet.
Randfälle systematisch bestimmen und im Entwurf berücksichtigen.
Kurz aufgefrischt
Vorausgesetzt werden die vier Eigenschaften eines und die drei Grundbausteine Folge, Auswahl und Wiederholung. Bei Unsicherheit lies Was ist ein Algorithmus? und Die drei Grundbausteine.
Neu ist hier die Frage, wie man auf einen Algorithmus kommt und wie man begründet, dass er stimmt.
Schrittweise Verfeinerung
Die Methode besteht darin, das Problem zunächst in groben Schritten zu beschreiben und jeden Schritt anschließend zu verfeinern, bis er unmittelbar umsetzbar ist.
Stufe 1, das ganze Problem in einem Satz:
Werte die Klassenarbeit aus.
Stufe 2, in drei Schritte zerlegt:
1. Punkte aller Schüler einlesen
2. Aus den Punkten Noten berechnen
3. Ergebnisse ausgeben
Stufe 3, Schritt 2 weiter verfeinert:
2.1 Für jeden Schüler:
2.2 Prozentsatz aus Punkten und Höchstpunktzahl berechnen
2.3 Aus dem Prozentsatz die Note bestimmen
Stufe 4, Schritt 2.3 weiter verfeinert:
2.3.1 Wenn Prozent >= 87 dann Note 1
2.3.2 sonst wenn Prozent >= 73 dann Note 2
2.3.3 sonst wenn Prozent >= 59 dann Note 3
2.3.4 ...
Jetzt ist jeder Schritt so einfach, dass man ihn ohne Nachdenken hinschreiben kann. Das ist das Abbruchkriterium: Verfeinert wird, bis ein Schritt offensichtlich umsetzbar ist.
🔴 Der Gewinn liegt nicht nur in der Übersicht. Auf jeder Stufe kann man prüfen, ob die Zerlegung vollständig ist, ohne sich um die tieferen Ebenen zu kümmern. Fehlt in Stufe 2 der Punkt „Ergebnisse ausgeben“, fällt das dort auf und nicht erst nach zweihundert Zeilen Quelltext.
Lies die vier Stufen von oben nach unten und achte auf die Überschriften: Ab Stufe 3 wird nur noch ein einziger Schritt weiter aufgeklappt, alles andere bleibt stehen. Genau das ist der Gewinn der Methode. Auf jeder Stufe kannst du prüfen, ob die Zerlegung vollständig ist, ohne dich um die tieferen Ebenen zu kümmern, fehlte in Stufe 2 der Punkt „Ergebnisse ausgeben“, fiele es dort sofort auf und nicht erst nach zweihundert Zeilen Quelltext. Und das Abbruchkriterium liest du an der letzten Stufe ab: Verfeinert wird, bis ein Schritt so einfach ist, dass man ihn ohne Nachdenken hinschreiben kann.
Struktogramme
Ein stellt einen als ineinandergeschachtelte Kästen dar. Sein Vorteil gegenüber Pfeildiagrammen: Man kann keine unstrukturierten Sprünge zeichnen, weil ein Kasten immer vollständig in einem anderen liegt.
Die drei Grundbausteine sehen so aus:
Folge: Auswahl: Wiederholung:
+------------------+ +------------------+ +--------------------+
| Anweisung 1 | | \ Bedingung / | | solange Bedingung |
+------------------+ | \ / | | +----------------+ |
| Anweisung 2 | | ja \ / nein| | | Anweisung | |
+------------------+ +-------+----------+ | +----------------+ |
| dann | sonst | +--------------------+
+-------+----------+
Verschachteln ist ausdrücklich vorgesehen: In einem Wiederholungsrahmen darf eine Auswahl stehen und darin wieder eine Wiederholung. Genau daraus entsteht die Ausdruckskraft.
Vom Struktogramm zum Pseudocode ist es dann nur noch eine Übersetzung: Jeder Kasten wird eine Zeile, jede Schachtelung eine Einrückung.
Dieselbe Zerlegung als Struktogramm
Das ist der Baum von eben, nur in der anderen Darstellung, vergleiche Kasten für Kasten. Was der Baum als Ebenen zeigt, zeigt das als Schachtelung: Die beiden Schritte 2.2 und 2.3 liegen innerhalb des Wiederholungsrahmens, und man sieht auf einen Blick, was je Schüler passiert und was nur einmal. Der eigentliche Vorteil dieser Form steckt in dem, was du nicht zeichnen kannst: Ein Kasten liegt immer vollständig in einem anderen, also gibt es keine Sprünge quer durch den Ablauf. Und der Weg zum Programm ist danach nur noch eine Übersetzung, jeder Kasten wird eine Zeile, jede Schachtelung eine Einrückung.
Den Entwurf prüfen: Ablaufsinn
Ein Entwurf ist erst dann fertig, wenn man ihn geprüft hat, und geprüft heißt: mit konkreten Werten durchgespielt.
Das Werkzeug dafür kennst du, es ist die Wertetabelle: eine Spalte je , eine Zeile je Durchlauf. Man wählt Beispielwerte, deren Ergebnis man unabhängig kennt, und vergleicht.
Wichtig ist die Auswahl der Beispiele. Ein einziger typischer Fall genügt nie, denn die Fehler sitzen an den Rändern.
Randfälle systematisch bestimmen
Statt zu raten, geht man eine feste Liste durch. Für jede Größe im fragt man:
| Frage | typischer Randfall |
|---|---|
| Was, wenn es nichts gibt? | leere Liste, null Schüler |
| Was, wenn es genau eines gibt? | ein Schüler, ein Durchlauf |
| Was am kleinsten Wert? | 0 Punkte |
| Was am größten Wert? | volle Punktzahl |
| Was genau an der Grenze? | exakt 87 Prozent |
| Was bei unerlaubten Werten? | negative Punkte, Text statt Zahl |
Besonders die Zeile „genau an der Grenze“ verdient Aufmerksamkeit. Bei einer Notengrenze von 87 Prozent muss festgelegt sein, ob 87,0 noch eine 1 ist oder schon eine 2. Diese Entscheidung trifft der Vergleichsoperator, und ein statt verschiebt sie.
Ein Zeichen, eine Note Unterschied
Drei Werte, dicht beieinander, und zwei Fassungen desselben , sie unterscheiden sich um ein einziges Zeichen. Geh die Zeilen von oben nach unten durch: Bei 87,1 und bei 86,9 Prozent sind sich beide einig. Genau auf der Grenze gehen sie auseinander, und für den Schüler mit exakt 87,0 Prozent ist das der Unterschied zwischen einer 1 und einer 2. Deshalb steht in der Randfallliste die Zeile „genau an der Grenze“: Sie ist der Fall, den man beim Testen fast immer übergeht, weil er so unwahrscheinlich aussieht und den ein Rechner regelmäßig trifft, weil Prozentwerte aus glatten Punktzahlen entstehen.
Begründen statt hoffen: die Invariante
Ein Durchspielen zeigt, dass der für diese Werte stimmt. Es zeigt nicht, dass er immer stimmt. Dafür braucht man ein Argument.
Das wichtigste Werkzeug dazu ist die Invariante: eine Aussage, die vor der gilt und die jeder Durchlauf erhält.
Beispiel, Summe der Zahlen von 1 bis :
summe := 0
i := 1
solange i <= n:
summe := summe + i
i := i + 1
Invariante: „ enthält die Summe aller Zahlen von 1 bis .“
Prüfen wir sie in drei Schritten, und genau diese drei gehören zu jeder Begründung:
Vor der Schleife gilt sie: und , also die Summe von 1 bis 0, und die ist leer, also 0. Stimmt.
Jeder Durchlauf erhält sie: Galt sie vorher, so wird addiert und danach um eins erhöht. Danach enthält die Summe bis zum neuen . Stimmt weiterhin.
Nach der Schleife ist die Bedingung falsch, also , und da genau um eins wächst, ist . Die Invariante liefert dann: ist die Summe von 1 bis . Genau das war gesucht.
Damit ist die Richtigkeit für alle begründet und nicht nur für ausprobierte Werte. Das ist der Unterschied zwischen Testen und Begründen, und beides hat seinen Platz: Testen findet Fehler, Begründen zeigt ihre Abwesenheit.
Die Invariante Zeile für Zeile geprüft
Die rechte Spalte ist die Invariante: „ enthält die Summe aller Zahlen von 1 bis .“ Prüfe sie in jeder Zeile selbst nach, indem du die dritte und die vierte Spalte vergleichst. Sie stimmen überein, in jeder Zeile. Und jetzt der Schritt, der Testen von Begründen unterscheidet: Die erste Zeile zeigt, dass die Aussage vor der gilt. Jede weitere Zeile zeigt, dass ein Durchlauf sie erhält. Beides zusammen gilt dann für beliebig viele Durchläufe, also auch für , ohne dass man tausend Zeilen schreiben müsste. Nach der Schleife ist , und die Invariante liefert die Summe von 1 bis , genau das Gesuchte. Testen findet Fehler; dieses Argument zeigt ihre Abwesenheit.
Auch die Endlichkeit gehört begründet
Zur Richtigkeit kommt die Frage, ob die überhaupt endet. Dafür genügt der Hinweis auf eine Größe, die sich in eine Richtung bewegt und eine Schranke erreichen muss:
startet bei 1, wächst in jedem Durchlauf um genau 1 und wird nie verkleinert; ändert sich nicht. Eine streng wachsende ganze Zahl überschreitet jede feste Schranke nach endlich vielen Schritten. Also endet die Schleife nach höchstens Durchläufen.
Ein vollständiger Entwurf beantwortet damit drei Fragen: Tut er das Richtige? Hört er auf? Was passiert an den Rändern?
Ein Problem schrittweise verfeinern
Entwirf durch schrittweise Verfeinerung einen , der aus einer Liste von Messwerten den größten, den kleinsten und den Mittelwert bestimmt.
- 1
Stufe 1:
Werte die Messreihe aus. - 2
Stufe 2, grobe Schritte:
1. Messwerte einlesen 2. Größten, kleinsten und Mittelwert bestimmen 3. Ergebnisse ausgebenHier lohnt schon die Prüfung: Fehlt etwas? Ja, der Fall einer leeren Liste ist nicht bedacht. Also ergänzen wir Schritt 0: „Wenn die Liste leer ist, Meldung ausgeben und beenden.“
- 3
Stufe 3, Schritt 2 verfeinert. Alle drei Größen lassen sich in einem Durchlauf bestimmen:
2.1 max := erster Wert 2.2 min := erster Wert 2.3 summe := erster Wert 2.4 Für jeden weiteren Wert w: 2.5 wenn w > max dann max := w 2.6 wenn w < min dann min := w 2.7 summe := summe + w 2.8 mittel := summe / Anzahl - 4
Warum mit dem ersten Wert starten und nicht mit 0? Weil bei lauter negativen Messwerten ein Startwert 0 für falsch wäre: Er bliebe stehen, obwohl kein Messwert so groß ist. Der erste Wert ist dagegen immer ein tatsächlich vorkommender.
- 5
Randfälle prüfen: Leere Liste ist durch Schritt 0 abgefangen. Genau ein Wert: Die läuft nullmal, max, min und Mittelwert sind dieser eine Wert. Richtig. Alle Werte gleich: max und min sind gleich, der Mittelwert ebenso. Richtig.
Vier Stufen, ein einziger Durchlauf für alle drei Größen, Startwerte aus dem ersten Element statt aus 0.
Eine Invariante aufstellen und prüfen
Ein zählt, wie viele Zahlen einer Liste größer als 100 sind. Stelle die Invariante auf und begründe die Richtigkeit.
- 1
Der Algorithmus:
anzahl := 0 i := 1 solange i <= laenge: wenn liste[i] > 100 dann anzahl := anzahl + 1 i := i + 1 - 2
Invariante formulieren. Man fragt: Was ist nach jedem Durchlauf wahr? Antwort: „ enthält die Anzahl der Elemente unter den ersten , die größer als 100 sind.“
- 3
Gilt sie vorher? Vor der ist und , also geht es um die ersten 0 Elemente. Unter keinem Element sind 0 größer als 100. Stimmt.
- 4
Bleibt sie erhalten? Ein Durchlauf betrachtet Element . Ist es größer als 100, wird um eins erhöht, sonst nicht; danach wächst um eins. In beiden Fällen zählt danach genau die passenden unter den ersten . Stimmt.
- 5
Was folgt am Ende? Die Schleife endet, wenn , und da um genau eins wächst, ist . Die Invariante liefert: zählt die passenden unter den ersten Elementen, also unter allen. Das war gesucht.
Die Richtigkeit ist für jede Liste begründet, nicht nur für ausprobierte. Genau das leistet eine Invariante.
Typischer Fehler
„Ich habe es mit drei Beispielen getestet, es funktioniert. Also ist der richtig.“
Ein Test kann die Anwesenheit von Fehlern zeigen, niemals ihre Abwesenheit. Drei gelungene Läufe belegen genau drei Fälle.
Das Gegenbeispiel ist leicht gebaut. Ein Algorithmus, der das Maximum sucht und dafür mit 0 vorbelegt, arbeitet für alle positiven Zahlen einwandfrei. Testet man mit den Werten 5, 12 und 7, ist das Ergebnis dreimal richtig. Bei den Werten , , liefert er 0, und 0 kommt in der Liste gar nicht vor.
Wer sollte diesen Fall testen? Genau darum geht es: Man findet ihn nicht durch mehr Beispiele, sondern durch systematisches Fragen nach den Rändern, hier „was, wenn alle Werte negativ sind?“.
Die drei Prüfungen ergänzen einander und ersetzen sich nicht:
| Prüfung | zeigt | zeigt nicht |
|---|---|---|
| Durchspielen mit Beispielen | Fehler in diesen Fällen | Richtigkeit allgemein |
| Randfälle systematisch | die typischen Lücken | ungewöhnliche Kombinationen |
| Invariante | Richtigkeit für alle Eingaben | Tippfehler in der Umsetzung |
Deshalb gehören zu einem fertigen Entwurf alle drei, und die Reihenfolge ist die des Aufwands: erst begründen, dann Ränder abfragen, dann testen.
Übung 1
leichtNenne für einen , der den Durchschnitt einer Zahlenliste berechnet, vier Randfälle und jeweils das erwartete Verhalten.
Tipp anzeigen
Gehe die sechs Fragen der Randfallliste durch.
Lösung anzeigen
Leere Liste: Der Durchschnitt ist nicht definiert, weil durch 0 geteilt würde. Erwartet wird eine Meldung, kein Absturz und kein erfundener Wert.
Genau ein Wert: Der Durchschnitt ist dieser Wert selbst.
Alle Werte gleich: Der Durchschnitt ist dieser Wert.
Negative Werte: Der Durchschnitt darf negativ sein; ein Algorithmus, der nur positive Werte annimmt, wäre falsch.
Weitere sinnvolle Fälle: sehr große Werte (Bereichsüberschreitung bei der Summe) und Text statt Zahl (unerlaubte Eingabe).
Detaillierte Schritterklärung anzeigen
Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.
✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.
- 1
Randfälle systematisch erzeugen statt sie zu erraten
Randfälle findet man nicht durch Nachdenken über die Aufgabe, sondern durch eine feste Frageliste: Was ist der kleinste mögliche Fall? Der zweitkleinste? Was, wenn alle Werte gleich sind? Was liegt außerhalb des Erwarteten? Was ist sehr groß? Was hat den falschen Typ?
- 2
Die leere Liste: kein Absturz und kein erfundener Wert
Leere Liste: Der Durchschnitt ist nicht definiert, weil durch 0 geteilt würde. Erwartet wird eine Meldung, kein Absturz und vor allem kein erfundener Wert wie 0.
- 3
Die Fälle mit bekanntem Ergebnis: genau ein Wert, alle gleich
Genau ein Wert: Der Durchschnitt ist dieser Wert selbst. Alle Werte gleich: ebenfalls dieser Wert. Beide Fälle sind besonders wertvoll, weil man das richtige Ergebnis vorher kennt, ohne zu rechnen.
- 4
Negative Werte und die weiteren Fälle
Negative Werte: Der Durchschnitt darf negativ sein; ein Algorithmus, der nur positive Werte annimmt, wäre falsch. Weitere sinnvolle Fälle: sehr große Werte (Bereichsüberschreitung bei der Summe) und Text statt Zahl (unerlaubte Eingabe).
Übung 2
mittelEntwirf einen , der prüft, ob eine Zahl eine Primzahl ist.
a) Zerlege das Problem in zwei Verfeinerungsstufen. b) Schreibe den Pseudocode. c) Stelle die Invariante der auf und begründe die Richtigkeit. d) Nenne drei Randfälle und prüfe deinen Entwurf daran.
Tipp anzeigen
Eine Zahl ist prim, wenn sie außer 1 und sich selbst keinen Teiler hat.
Lösung anzeigen
a) Stufe 1: „Prüfe, ob n eine Primzahl ist.“ Stufe 2:
- Sonderfälle behandeln (n kleiner als 2 ist keine Primzahl)
- Alle möglichen Teiler durchprobieren
- Ergebnis ausgeben
b) Pseudocode:
LIES n WENN n < 2 DANN SCHREIBE "keine Primzahl" SONST istPrim := wahr t := 2 SOLANGE t * t <= n UND istPrim WIEDERHOLE WENN n mod t = 0 DANN istPrim := falsch t := t + 1 ENDE SOLANGE SCHREIBE istPrim ENDE WENN
c) Invariante: „ ist genau dann noch wahr, wenn keine der bisher geprüften Zahlen von 2 bis ein Teiler von ist.“
Gilt vorher: , geprüft wurde nichts, ist wahr. Stimmt. Bleibt erhalten: Jeder Durchlauf prüft genau . Ist es ein Teiler, wird falsch; sonst bleibt es wahr. Danach wächst um eins. Stimmt weiterhin. Am Ende: Die Schleife endet, wenn oder falsch ist. Im ersten Fall wurden alle Teiler bis geprüft, und das genügt: Hätte einen Teiler größer als , so hätte es auch einen kleineren, denn Teiler treten paarweise auf. Also ist prim. Im zweiten Fall wurde ein Teiler gefunden.
d) n = 1: kleiner als 2, wird als „keine Primzahl“ gemeldet. Richtig. n = 2: Die Schleifenbedingung ist von Anfang an falsch, die Schleife läuft nullmal, bleibt wahr. Richtig, 2 ist prim. n = 4: , ist wahr, , also nicht prim. Richtig.
Detaillierte Schritterklärung anzeigen
Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.
✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.
- 1
Erst die Sonderfälle abtrennen
Bevor man an die Schleife geht, klärt man die Fälle, die gar nicht in das allgemeine Verfahren passen. Für Zahlen kleiner als 2 ist die Frage per Definition beantwortet, und man erspart sich später Sonderregeln in der Schleife.
Zwischenergebnis
n < 2 wird vorab abgefangen.
Sonderfälle nach vorn zu ziehen macht den Hauptteil sauber. Wer sie in die Schleife einbaut, muss ihre Bedingung bei jedem Durchlauf mitprüfen, obwohl sie sich nie ändert.
- 2
Die Schleife: was wird eigentlich durchprobiert?
Geprüft wird, ob eine der Zahlen ab 2 ein Teiler ist. Ein Teiler liegt vor, wenn die Division ohne Rest aufgeht, also der Rest 0 ist.
n \bmod t = 0 ;\Leftrightarrow; t \text{ ist Teiler von } n
Zwischenergebnis
Ein einziger gefundener Teiler genügt, um „keine Primzahl“ zu entscheiden.
- 3
Warum bis zur Wurzel genügt
Die Bedingung lautet und nicht . Der Grund ist ein Argument über Teilerpaare, kein Sparbeschluss.
n = a \cdot b ;\Rightarrow; \text{einer der beiden Faktoren} \le \sqrt{n}
Zwischenergebnis
Es genügt, bis zu prüfen.
- 4
Teil d): Randfälle einzeln durchspielen
Geprüft wird nicht mit einer großen Zahl, sondern mit den kleinen und den Grenzfällen. Bei n = 2 ist entscheidend, ob die Schleife nullmal läuft; das prüft man, indem man die Bedingung mit den Startwerten einsetzt.
t = 2,\quad t \cdot t = 4 \not\le 2 ;\Rightarrow; \text{null Durchläufe}
Zwischenergebnis
istPrim bleibt wahr, 2 wird korrekt als Primzahl erkannt.
Genau hier zeigt sich der Nutzen der kopfgesteuerten Schleife: Sie darf nullmal laufen. Eine fußgesteuerte hätte bei n = 2 einmal geprüft und dabei nichts kaputtgemacht, bei anderer Formulierung aber leicht.
Übung 3
schwerEin soll aus einer Liste von Tagestemperaturen die längste Folge aufeinanderfolgender Tage mit Frost (Temperatur unter 0) bestimmen.
a) Zerlege das Problem und schreibe den Pseudocode. b) Welche zwei Zählvariablen brauchst du, und warum reicht eine nicht? c) Stelle die Invariante auf. d) Prüfe deinen Entwurf an den Listen [3, -1, -2, 4], [-1, -2, -3] und der leeren Liste.
Tipp anzeigen
Zu b): Eine Zählung läuft mit, die andere merkt sich das beste bisher gesehene Ergebnis.
Lösung anzeigen
a) Stufe 2: 1. Liste durchlaufen. 2. Frostfolgen mitzählen. 3. Längste merken. 4. Ausgeben.
Pseudocode:
aktuell := 0 laengste := 0 FÜR jeden Wert t IN liste WIEDERHOLE WENN t < 0 DANN aktuell := aktuell + 1 WENN aktuell > laengste DANN laengste := aktuell SONST aktuell := 0 ENDE WENN ENDE FÜR SCHREIBE laengste
b) Man braucht für die gerade laufende Frostfolge und für die beste bisher gesehene. Eine reicht nicht, weil beim Ende einer Folge der laufende Zähler zurückgesetzt werden muss; ohne die zweite Variable wäre das bisherige Ergebnis dann verloren. Der Fall [-1, -2, 5, -3] zeigt es: Nach dem 5 wird auf 0 gesetzt, und die 2 aus der ersten Folge muss anderswo aufbewahrt sein.
c) Invariante: „ ist die Länge der längsten Frostfolge unter den bisher betrachteten Tagen, und ist die Länge der Frostfolge, die mit dem zuletzt betrachteten Tag endet.“
Sie gilt vor der (beide 0, keine Tage betrachtet), bleibt bei jedem Durchlauf erhalten (Frosttag verlängert die laufende Folge und aktualisiert gegebenenfalls das Beste; ein frostfreier Tag beendet die laufende Folge), und liefert nach dem letzten Tag genau das gesuchte Ergebnis.
d) [3, -1, -2, 4]: 3 setzt aktuell auf 0. ergibt aktuell 1, laengste 1. ergibt aktuell 2, laengste 2. 4 setzt aktuell auf 0. Ergebnis 2. Richtig. [-1, -2, -3]: aktuell wächst auf 3, laengste ebenfalls 3. Ergebnis 3. Richtig, und dieser Fall prüft, ob das Ergebnis auch dann stimmt, wenn die längste Folge am Ende liegt und kein frostfreier Tag mehr folgt. Genau hier scheitern Entwürfe, die das Ergebnis erst beim Zurücksetzen aktualisieren. Leere Liste: Die Schleife läuft nullmal, laengste bleibt 0. Ergebnis 0. Richtig, denn ohne Tage gibt es keine Frostfolge.
Detaillierte Schritterklärung anzeigen
Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.
✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.
- 1
a) Das Problem zerlegen, bevor Pseudocode entsteht
Die Zerlegung: 1. Liste durchlaufen. 2. Frostfolgen mitzählen. 3. Die längste merken. 4. Ausgeben. Erst danach der Pseudocode mit zwei Zählern, einer Schleife und einer Auswahl darin.
; ; für jeden Wert prüfen und zurücksetzen
- 2
b) Warum eine Zählvariable nicht reicht
Man braucht für die gerade laufende Frostfolge und für die beste bisher gesehene. Eine reicht nicht, weil beim Ende einer Folge der laufende Zähler zurückgesetzt werden muss, ohne die zweite Variable wäre das bisherige Ergebnis dann verloren.
- 3
c) Die Invariante aufstellen und in drei Punkten prüfen
Invariante: „ ist die Länge der längsten Frostfolge unter den bisher betrachteten Tagen, und ist die Länge der Frostfolge, die mit dem zuletzt betrachteten Tag endet.“ Geprüft wird in drei Punkten: Gilt sie vor der Schleife (beide 0, keine Tage betrachtet, ja)? Bleibt sie bei jedem Durchlauf erhalten? Liefert sie nach dem letzten Tag das Gesuchte?
- 4
d) An drei Listen prüfen, jede prüft etwas anderes
: 3 setzt aktuell auf 0; ergibt 1, ergibt 2 (laengste 2); 4 setzt zurück. Ergebnis 2. : aktuell wächst auf 3, laengste ebenso. Ergebnis 3. Leere Liste: Die Schleife läuft nullmal, laengste bleibt 0. Ergebnis 0.
Zusammenfassung
Ein entsteht nicht beim Tippen, sondern durch schrittweise Verfeinerung: Das Problem wird grob zerlegt, und jeder Schritt wird weiter zerlegt, bis er offensichtlich umsetzbar ist. Auf jeder Stufe lässt sich prüfen, ob die Zerlegung vollständig ist, und dort fällt Fehlendes auf, statt erst im Quelltext. stellen das Ergebnis als geschachtelte Kästen dar und schließen unstrukturierte Sprünge zeichnerisch aus; die Übersetzung in Pseudocode ist danach reine Schreibarbeit. Geprüft wird ein Entwurf auf drei Weisen, die einander ergänzen: Durchspielen mit Beispielwerten findet Fehler in genau diesen Fällen, eine systematische Randfallliste deckt die typischen Lücken auf, und eine Invariante begründet die Richtigkeit für alle Eingaben. Dazu gehört die Begründung der Endlichkeit über eine Größe, die sich streng auf eine Schranke zubewegt. Ein fertiger Entwurf beantwortet damit drei Fragen: Tut er das Richtige, hört er auf, und was passiert an den Rändern?


