Lektion 5 von 8

Felder und die Grundmuster

Viele Werte, ein Name: das Feld. Mit der Zählschleife gehst du alle Elemente durch, und daraus entstehen die Grundmuster, die in Prüfungsaufgaben immer wieder auftauchen: Summe, Durchschnitt, Maximum, Zählen und Suchen. Wer die fünf Muster sicher zeichnen kann, erkennt sie später in vielen Aufgabentexten wieder.

  • Etwa 35 Minuten
  • 1 Leseaufgabe, 2 Zeichenaufgaben, 1 Ergänzungsaufgabe, 4 Quizfragen
  • Papier und Stift genügen

Felder: viele Werte unter einem Namen

Bisher hatte jede Variable genau einen Wert. Sobald eine Aufgabe von „den Messwerten“, „allen Kunden“ oder „einer Liste von Preisen“ spricht, brauchst du ein Feld (Array). Stell dir ein Feld als Reihe nummerierter Fächer vor: Jedes Fach enthält einen Wert, und die Nummer des Fachs heißt Index. Das Feld zahlen mit vier Werten sieht so aus:

Index i1234
zahlen[i]4927

Auf ein einzelnes Fach greifst du mit dem Index in eckigen Klammern zu: zahlen[2] ist 9, zahlen[4] ist 7. Der Index darf auch eine Variable sein, und genau das macht Felder so nützlich: zahlen[i] meint je nach Wert von i ein anderes Fach. Die Anzahl der Elemente heißt im Kurs n; manche Aufgaben schreiben stattdessen laenge(zahlen) oder geben die Anzahl im Text fest vor („ein Feld mit 20 Messwerten“).

Alle Elemente der Reihe nach anzusehen ist die Grundbewegung bei Feldern. Weil die Anzahl vorher feststeht, ist die Zählschleife aus Lektion 3 das passende Werkzeug. Der Zähler ist zugleich der Index:

Struktogramm

Alle Elemente ausgeben
für i = 1 bis n
Ausgabe zahlen[i]

Pseudocode

FÜR i = 1 BIS n
    AUSGABE zahlen[i]
ENDE FÜR

Für das Feld oben werden nacheinander 4, 9, 2 und 7 ausgegeben. Jedes der folgenden Muster ist nichts anderes als dieser Durchlauf mit etwas Zusatz davor, im Rumpf und danach.

Summe und Durchschnitt

Das erste Muster: alle Werte zusammenzählen. Dafür braucht es eine Variable, die vor der Schleife auf 0 gesetzt wird und in jedem Durchlauf das aktuelle Element dazubekommt. Eine solche Variable heißt Akkumulator („Sammler“).

Struktogramm

Summe
summe = 0
für i = 1 bis n
summe = summe + zahlen[i]
Ausgabe summe

Pseudocode

summe = 0
FÜR i = 1 BIS n
    summe = summe + zahlen[i]
ENDE FÜR
AUSGABE summe

Der Schreibtischtest (Wertetabelle) für zahlen = [4, 9, 2, 7] mit n = 4:

Schrittizahlen[i]summeAusgabe
Start··0·
summe = 0 + 4144·
summe = 4 + 92913·
summe = 13 + 23215·
summe = 15 + 74722·
Schleife beendet, Ausgabe5·2222
Summe von [4, 9, 2, 7]: 22. Am Ende steht i auf 5, die Prüfung 5 > 4 beendet die Schleife. Die Ausgabe steht nach der Schleife, nicht im Rumpf; sonst würden alle Zwischensummen ausgegeben.

Der Durchschnitt ist die Summe geteilt durch die Anzahl. Er kommt nach der Schleife dazu, als eine Anweisung. Wir setzen n >= 1 voraus (mindestens ein Wert), sonst würde durch 0 geteilt:

Struktogramm

Durchschnitt
summe = 0
für i = 1 bis n
summe = summe + zahlen[i]
durchschnitt = summe / n
Ausgabe durchschnitt

Pseudocode

summe = 0
FÜR i = 1 BIS n
    summe = summe + zahlen[i]
ENDE FÜR
durchschnitt = summe / n
AUSGABE durchschnitt

Für unser Feld: 22 / 4 = 5,5. Achte auf den Datentyp: durchschnitt muss eine Kommazahl sein, und die Division ist das / mit Nachkommastellen, nicht DIV. Mit ganzzahliger Division käme 5 heraus, und das ist in vielen Lösungshinweisen ein eigener Abzug. Wenn eine Aufgabe die Datentypen nennen lässt, schreibe „summe: Ganzzahl, durchschnitt: Kommazahl“ dazu.

Maximum und Minimum mit Index

Das größte Element finden: Du merkst dir einen Kandidaten und vergleichst jedes weitere Element mit ihm. Ist das Element größer, wird es der neue Kandidat. Oft will die Aufgabe nicht nur den Wert, sondern auch die Stelle, an der er steht; dann merkst du dir den Index gleich mit. Wir setzen n >= 1 voraus (mindestens ein Wert), damit der Startkandidat existiert.

Struktogramm

Maximum mit Index
max = zahlen[1]
pos = 1
für i = 2 bis n
zahlen[i] > maxjanein
max = zahlen[i]
pos = i
Ausgabe max, pos

Pseudocode

max = zahlen[1]
pos = 1
FÜR i = 2 BIS n
    WENN zahlen[i] > max DANN
        max = zahlen[i]
        pos = i
    ENDE WENN
ENDE FÜR
AUSGABE max, pos
Prüfungizahlen[i]maxposAusgabe
Start: max = zahlen[1]··41·
9 > 4: ja2992·
2 > 9: nein3292·
7 > 9: nein4792·
Schleife beendet, Ausgabe5·929, 2
Maximum von [4, 9, 2, 7]: der Wert 9 an Position 2. Die Schleife beginnt bei 2, weil das erste Element schon der Startkandidat ist.

Das Minimum ist dieselbe Struktur mit umgedrehtem Vergleich: Der Kandidat wird ersetzt, wenn das Element kleiner ist.

Minimum mit Index
min = zahlen[1]
pos = 1
für i = 2 bis n
zahlen[i] < minjanein
min = zahlen[i]
pos = i
Ausgabe min, pos
Für [4, 9, 2, 7]: min startet mit 4; 9 < 4 nein, 2 < 4 ja (min = 2, pos = 3), 7 < 2 nein. Ausgabe 2, 3.

Kommt der größte Wert mehrfach vor, behält > die erste Stelle, weil ein gleich großes Element die Bedingung nicht erfüllt. Mit >= würde die letzte Stelle gemerkt. Wenn die Aufgabe dazu nichts sagt, sind beide Varianten in Ordnung; sag im Zweifel in einem Satz dazu, welche du gewählt hast.

Zählen mit Bedingung

„Wie viele Werte sind größer als 5?“ Das Muster kennst du aus Lektion 4: ein Zähler, der vor der Schleife auf 0 gesetzt wird, und eine Verzweigung im Rumpf, in deren Ja-Zweig der Zähler um 1 erhöht wird. Neu ist nur, dass die Bedingung ein Feldelement prüft.

Struktogramm

Werte über 5 zählen
anzahl = 0
für i = 1 bis n
zahlen[i] > 5janein
anzahl = anzahl + 1
Ausgabe anzahl

Pseudocode

anzahl = 0
FÜR i = 1 BIS n
    WENN zahlen[i] > 5 DANN
        anzahl = anzahl + 1
    ENDE WENN
ENDE FÜR
AUSGABE anzahl
Prüfungizahlen[i]anzahlAusgabe
Start··0·
4 > 5: nein140·
9 > 5: ja291·
2 > 5: nein321·
7 > 5: ja472·
Schleife beendet, Ausgabe5·22
Zwei Werte von [4, 9, 2, 7] liegen über 5: die 9 und die 7.

Der Unterschied zur Summe: Beim Zählen kommt in jedem Treffer + 1 dazu, bei der Summe + zahlen[i]. Beides lässt sich kombinieren, etwa „Summe aller geraden Werte“: Verzweigung mit zahlen[i] MOD 2 == 0, im Ja-Zweig summe = summe + zahlen[i].

Lineare Suche

„Kommt der Wert 2 im Feld vor, und wenn ja, an welcher Stelle?“ Die lineare Suche geht die Elemente von vorn nach hinten durch und vergleicht jedes mit dem gesuchten Wert. Zwei Dinge musst du dir merken: ob etwas gefunden wurde (ein Merker vom Typ Wahrheitswert) und wo (die Position). Sobald der Wert gefunden ist, darf die Suche aufhören. Deshalb ist die Standardform eine kopfgesteuerte Schleife mit doppelter Bedingung:

Struktogramm

Lineare Suche
Eingabe gesucht
gefunden = falsch
i = 1
solange i <= n UND NICHT gefunden
zahlen[i] == gesuchtjanein
gefunden = wahr
position = i
i = i + 1
gefundenjanein
Ausgabe "Position", position
Ausgabe "nicht gefunden"

Pseudocode

EINGABE gesucht
gefunden = falsch
i = 1
SOLANGE i <= n UND NICHT gefunden
    WENN zahlen[i] == gesucht DANN
        gefunden = wahr
        position = i
    ENDE WENN
    i = i + 1
ENDE SOLANGE
WENN gefunden DANN
    AUSGABE "Position", position
SONST
    AUSGABE "nicht gefunden"
ENDE WENN

Die Schleife läuft, solange noch Elemente übrig sind (i <= n) und noch nichts gefunden wurde (NICHT gefunden). Sobald eine der beiden Bedingungen kippt, endet sie: entweder am Feldende oder nach dem Treffer. Der Schreibtischtest für die Suche nach 2 in [4, 9, 2, 7]:

Prüfungizahlen[i]gefundenpositionAusgabe
Start: i = 11·falsch··
1 <= 4 UND NICHT falsch: ja; 4 == 2: nein14falsch··
2 <= 4 UND NICHT falsch: ja; 9 == 2: nein29falsch··
3 <= 4 UND NICHT falsch: ja; 2 == 2: ja32wahr3·
4 <= 4 UND NICHT wahr: nein, Schleife endet4·wahr3·
gefunden: ja, Ausgabe4·wahr3Position 3
Suche nach 2: Treffer im dritten Durchlauf. Die 7 wird nicht mehr angesehen. Die Spalte i zeigt den Wert bei der Prüfung; am Ende jedes Durchlaufs erhöht i = i + 1 den Zähler, deshalb steht i in der nächsten Zeile um 1 höher.

Würde nach 5 gesucht, bliebe gefunden falsch, i liefe bis 5, die Bedingung 5 <= 4 wäre falsch, und die Ausgabe wäre „nicht gefunden“. Die Verzweigung nach der Schleife entscheidet über die Ausgabe; im Rumpf selbst wird nichts ausgegeben.

Die Alternative ist eine Zählschleife mit Merker. Sie ist kürzer, läuft aber nach dem Treffer bis zum Feldende weiter und merkt sich bei mehrfach vorkommenden Werten die letzte Position:

Lineare Suche mit Zählschleife
Eingabe gesucht
gefunden = falsch
für i = 1 bis n
zahlen[i] == gesuchtjanein
gefunden = wahr
position = i
gefundenjanein
Ausgabe "Position", position
Ausgabe "nicht gefunden"
Gleichwertig, wenn die Aufgabe keinen Abbruch verlangt. Den Zähler i im Rumpf auf n zu setzen, um abzubrechen, ist keine Lösung: Der Zähler einer Zählschleife wird im Rumpf nicht verändert.

Merkregeln für alle Muster

  1. Startwert passend zum Muster: 0 für Summe und Zähler, 1 für ein Produkt, das erste Element für Maximum und Minimum, falsch für den gefunden-Merker.
  2. Eine Schleife über alle Elemente, der Zähler ist der Index. Grenzen zur Indexbasis passend: 1 bis n oder 0 bis n − 1.
  3. Ausgabe nach der Schleife, nicht im Rumpf. Im Rumpf wird nur gerechnet, verglichen und gemerkt.

Übungen

Leseaufgabe 5.1

Führen Sie einen Schreibtischtest durch: Gegeben ist das Feld zahlen = [3, 8, 5, 8, 1]; das erste Element hat den Index 1. Welche Werte gibt das Struktogramm aus? Lege die Spalten i, zahlen[i], max und pos an und notiere zu jedem Durchlauf, ob die Bedingung zutrifft.

Maximum mit Index
max = zahlen[1]
pos = 1
für i = 2 bis 5
zahlen[i] > maxjanein
max = zahlen[i]
pos = i
Ausgabe max, pos
Musterlösung anzeigen
Prüfungizahlen[i]maxposAusgabe
Start: max = zahlen[1]··31·
8 > 3: ja2882·
5 > 8: nein3582·
8 > 8: nein4882·
1 > 8: nein5182·
Schleife beendet, Ausgabe6·828, 2

Ausgabe: 8, 2. Die zweite 8 an Position 4 ändert nichts, weil 8 > 8 falsch ist; gemerkt bleibt die erste Fundstelle. Wer hier pos = 4 notiert, hat den Vergleich als >= gelesen.

Zeichenaufgabe 5.2

Entwerfen Sie ein Struktogramm: Gegeben ist ein Feld zahlen mit n Werten; das erste Element hat den Index 1. Es soll ausgegeben werden, wie viele Werte über dem Durchschnitt aller Werte liegen. Überlege zuerst, was du wissen musst, bevor du zählen kannst.

Musterlösung anzeigen
Werte über dem Durchschnitt zählen
summe = 0
für i = 1 bis n
summe = summe + zahlen[i]
durchschnitt = summe / n
anzahl = 0
für i = 1 bis n
zahlen[i] > durchschnittjanein
anzahl = anzahl + 1
Ausgabe anzahl

Zwei Schleifen nacheinander: Die erste bildet die Summe, daraus entsteht der Durchschnitt, die zweite zählt. In einer einzigen Schleife geht es nicht, weil der Durchschnitt erst feststeht, wenn alle Werte gesehen wurden. Probe mit [4, 9, 2, 7]: Summe 22, Durchschnitt 5,5, darüber liegen 9 und 7, Ausgabe 2. Der Zähler i darf in beiden Schleifen gleich heißen, weil die erste Schleife beendet ist, bevor die zweite beginnt.

So wird typischerweise bewertet

  • Erste Schleife über alle n Elemente bildet die Summe, Akkumulator vorher auf 0
  • Durchschnitt nach der ersten Schleife als summe / n (Kommazahl)
  • Zweite Schleife über alle Elemente mit Verzweigung zahlen[i] > durchschnitt
  • Zähler vor der zweiten Schleife auf 0, Erhöhung im Ja-Zweig, Ausgabe nach der Schleife
  • Gleichwertig: andere Schleifenart mit denselben Grenzen oder ein anderer Name für den zweiten Zähler; ein Zähler ab 0 nur mit Zugriff zahlen[i + 1]
Zeichenaufgabe 5.3

Entwerfen Sie ein Struktogramm: In einem Feld kunden stehen n Kundennummern; das erste Element hat den Index 1. Eine Kundennummer wird eingegeben. Kommt sie im Feld vor, soll ihre Position ausgegeben werden, sonst der Text „nicht gefunden“. Die Suche soll nach dem ersten Treffer beendet werden.

Musterlösung anzeigen
Kundennummer suchen
Eingabe gesucht
gefunden = falsch
i = 1
solange i <= n UND NICHT gefunden
kunden[i] == gesuchtjanein
gefunden = wahr
position = i
i = i + 1
gefundenjanein
Ausgabe "Position", position
Ausgabe "nicht gefunden"

Die kopfgesteuerte Schleife mit i <= n UND NICHT gefunden bricht nach dem Treffer ab. Der Merker startet mit falsch, die Position wird nur im Ja-Zweig gesetzt. Die Ausgabe hängt nach der Schleife am Merker, nicht an der Position, weil die Position bei Misserfolg gar keinen Wert hat. Probe: Für kunden = [1007, 1042, 1015] und gesucht = 1042 endet die Schleife nach dem zweiten Durchlauf mit Ausgabe „Position 2“; für 1099 läuft sie bis i = 4 durch und gibt „nicht gefunden“ aus.

So wird typischerweise bewertet

  • Eingabe der gesuchten Nummer, Merker gefunden mit Startwert falsch
  • Schleife über das Feld mit Vergleich kunden[i] == gesucht
  • Im Ja-Zweig Merker auf wahr und Position gemerkt
  • Ausgabe nach der Schleife per Verzweigung über den Merker: Position oder „nicht gefunden“
  • Gleichwertig: Zählschleife mit Merker ohne Abbruch, oder eine Position mit Startwert 0 als Merker (0 heißt „nicht gefunden“)
Ergänzungsaufgabe 5.4

Ergänzen Sie das Struktogramm an den Stellen (1) und (2): Es soll der kleinste Wert des Feldes zahlen mit n Elementen zusammen mit seiner Position ausgegeben werden; das erste Element hat den Index 1. Lücke (2) steht im Kopf der Verzweigung.

Minimum mit Index
(1)
pos = 1
für i = 2 bis n
(2)janein
min = zahlen[i]
pos = i
Ausgabe min, pos
Musterlösung anzeigen
Minimum mit Index
min = zahlen[1]
pos = 1
für i = 2 bis n
zahlen[i] < minjanein
min = zahlen[i]
pos = i
Ausgabe min, pos

(1) min = zahlen[1]: der Startkandidat ist das erste Element, passend dazu steht schon pos = 1 darunter und die Schleife beginnt bei 2. (2) zahlen[i] < min: kleiner, nicht größer; zahlen[i] <= min ist ebenfalls richtig, dann gilt bei gleichen Werten die letzte Fundstelle. Probe mit [6, 3, 9, 3]: min startet mit 6; 3 < 6 ja (min = 3, pos = 2); 9 < 3 nein; 3 < 3 nein. Ausgabe 3, 2. Wer in (1) min = 0 schreibt, bekommt für dieses Feld die Ausgabe 0, 1, obwohl keine 0 im Feld steht.

Jetzt selbst testen

Vier Fragen zu Feldern und den Grundmustern.

1 / 4

Ein Feld hat n Elemente, das erste Element hat den Index 0. Wie lautet die Zählschleife über alle Elemente?

2 / 4

Welcher Startwert ist für die Suche nach dem Maximum sicher?

3 / 4

Aufgabentext: „Geben Sie aus, wie viele Bestellungen einen Wert über 100 Euro haben.“ Welches Muster ist gemeint?

4 / 4

Die lineare Suche läuft mit „solange i <= n UND NICHT gefunden“. Was bewirkt der zweite Teil der Bedingung?