Grundlagen der Programmierung
Vorlesung 13
Aufgabe: Finde den zweitgröĂten Wert!
12
9
Wir brauchen zwei Variablen:
Array: {7, 3, 12, 9, 5}
| i | arr[i] | Vergleich | max | zweit |
|---|---|---|---|---|
| Start | - | - | 7 (arr[0]) | -â (sehr klein) |
| 1 | 3 | 3 > 7? â, 3 > -â? â | 7 | 3 |
| 2 | 12 | 12 > 7? â | 12 | 7 (altes max) |
| 3 | 9 | 9 > 12? â, 9 > 7? â | 12 | 9 |
| 4 | 5 | 5 > 12? â, 5 > 9? â | 12 | 9 |
#include <stdio.h>
#include <limits.h> // fĂŒr INT_MIN
int main()
{
int arr[5] = {7, 3, 12, 9, 5};
int n = 5;
int max = arr[0];
int zweit = INT_MIN; // noch KEIN Kandidat fĂŒr Platz 2
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
zweit = max; // Altes max wird zweit
max = arr[i]; // Neues max
}
else if (arr[i] > zweit)
{
zweit = arr[i]; // Neues zweit
}
}
printf("Maximum: %d, Zweithöchstes: %d\n", max, zweit);
return 0;
}
Es heiĂt nicht "das Ergebnis ist klein". INT_MIN ist nur ein Platzhalter fĂŒr "noch nichts gefunden".
max darf mit arr[0] starten â das erste Element ist ein gĂŒltiger erster Kandidat. FĂŒr zweit gibt es noch keinen: einen "Zweiten" hat man erst, wenn man zwei Elemente gesehen hat.
Die Zeile arr[i] > zweit ĂŒberschreibt nur, wenn das Element gröĂer ist. Der Platzhalter muss also kleiner als jeder mögliche Wert sein, damit der erste echte Kandidat sicher gewinnt.
â ïž zweit = 0 wĂ€re falsch bei negativen Arrays wie {-5, -9, -3} â kein Element ist > 0.
Gleiche Logik, nur mit < statt >:
int min = arr[0];
int zweit = INT_MAX; // GröĂter möglicher Wert
for (int i = 1; i < n; i++)
{
if (arr[i] < min)
{
zweit = min;
min = arr[i];
}
else if (arr[i] < zweit)
{
zweit = arr[i];
}
}
Aufgabe: Wie oft kommt jede Zahl vor?
2 kommt 3à vor · 3 kommt 2à vor · 5 kommt 3à vor
FĂŒr einen bestimmten Wert zĂ€hlen (bekanntes Muster!):
#include <stdio.h>
int main()
{
int arr[8] = {2, 5, 2, 3, 5, 2, 5, 3};
int n = 8;
int gesucht = 5;
int zaehler = 0;
for (int i = 0; i < n; i++)
{
if (arr[i] == gesucht)
{
zaehler++;
}
}
printf("%d kommt %d mal vor.\n", gesucht, zaehler);
return 0;
}
Die einfache Lösung zÀhlt nur einen Wert. Was, wenn wir alle gleichzeitig zÀhlen wollen?
int zaehler = 0;
...
zaehler++;
Eine Variable. ZĂ€hlt nur die 5. FĂŒr die 2 und die 3 brĂ€uchte ich je eine weitere VariableâŠ
int haeufigkeit[10] = {0};
Diese eine Zeile erzeugt 10 ZĂ€hler, alle auf 0 â einen fĂŒr jede mögliche Zahl 0â9.
Statt zu suchen, gibt jede mögliche Zahl (0â9) ihren eigenen ZĂ€hler-Eimer. FĂŒr jede Zahl im Array werfen wir einen Stein in ihren Eimer.
Eingabe: arr = {2, 5, 2, 3, 5, 2, 5, 3} â nacheinander lesen und einsortieren:
Steine im Eimer = wie oft die Zahl vorkam. Eimer 2 hat 3 Steine â die 2 kam 3Ă vor.
Der ZĂ€hler-Array = die Eimer. Der Index ist das Etikett (welche Zahl), der Inhalt die Strichliste (wie oft). Nur fĂŒr kleine positive Zahlen (z.B. 0-9):
#include <stdio.h>
int main()
{
int arr[8] = {2, 5, 2, 3, 5, 2, 5, 3};
int n = 8;
int haeufigkeit[10] = {0}; // ZĂ€hler fĂŒr 0-9, alle auf 0
/* HÀufigkeiten zÀhlen */
for (int i = 0; i < n; i++)
{
haeufigkeit[arr[i]]++; // gehe zu Eimer arr[i] â +1 Stein
}
/* Ausgabe */
for (int i = 0; i < 10; i++)
{
if (haeufigkeit[i] > 0)
printf("%d kommt %d mal vor\n", i, haeufigkeit[i]);
}
return 0;
}
arr = {2, 5, 2, 3, 5, 2, 5, 3} â bei jedem Schritt: haeufigkeit[arr[i]]++
| i | arr[i] | Aktion | haeufigkeit[0..9] |
|---|---|---|---|
| Start | â | alle 0 | [0,0,0,0,0,0,0,0,0,0] |
| 0 | 2 | haeufigkeit[2]++ | [0,0,1,0,0,0,0,0,0,0] |
| 1 | 5 | haeufigkeit[5]++ | [0,0,1,0,0,1,0,0,0,0] |
| 2 | 2 | haeufigkeit[2]++ | [0,0,2,0,0,1,0,0,0,0] |
| 3 | 3 | haeufigkeit[3]++ | [0,0,2,1,0,1,0,0,0,0] |
| 4 | 5 | haeufigkeit[5]++ | [0,0,2,1,0,2,0,0,0,0] |
| 5 | 2 | haeufigkeit[2]++ | [0,0,3,1,0,2,0,0,0,0] |
| 6 | 5 | haeufigkeit[5]++ | [0,0,3,1,0,3,0,0,0,0] |
| 7 | 3 | haeufigkeit[3]++ | [0,0,3,2,0,3,0,0,0,0] |
arr = {2, 5, 2, 3, 5, 2, 5, 3}
haeufigkeit[] (ZĂ€hler-Array):
Aufgabe: Gibt es Werte, die mehrfach vorkommen?
Die 7 kommt an Position 1 und 3 vor!
Verschachtelte Schleifen: Vergleiche jedes Element mit allen folgenden!
Wie beim HĂ€ndeschĂŒtteln in einer Reihe: Person i gibt jedem, der rechts von ihr steht, die Hand â dann ist jedes Paar genau einmal dran.
arr = {3, 7, 2, 7}
| i steht bei | vergleicht mit (j > i) |
|---|---|
| arr[0]=3 | 7 · 2 · 7 (3 Vergleiche) |
| arr[1]=7 | 2 · 7 â Treffer! (2 Vergleiche) |
| arr[2]=2 | 7 (1 Vergleich) |
| arr[3]=7 | â (rechts steht niemand) |
#include <stdio.h>
int main()
{
int arr[6] = {3, 7, 2, 7, 5, 1};
int n = 6;
int hatDuplikate = 0;
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++) // Nur nach rechts schauen!
{
if (arr[i] == arr[j])
{
printf("Duplikat: %d (Positionen %d und %d)\n",
arr[i], i, j);
hatDuplikate = 1;
}
}
}
if (!hatDuplikate)
printf("Keine Duplikate gefunden.\n");
return 0;
}
arr = {3, 7, 2, 7}
| i | j-Werte | Vergleiche |
|---|---|---|
| 0 | 1, 2, 3 | 3==7? â, 3==2? â, 3==7? â |
| 1 | 2, 3 | 7==2? â, 7==7? â Duplikat! |
| 2 | 3 | 2==7? â |
Aufgabe: Zwei Arrays zu einem kombinieren
Array A:
Array B:
âŹïž
Ergebnis C:
Wie zwei Kartenstapel zu einem: den ersten Stapel ablegen, den zweiten direkt dahinter anlegen. Zwei einfache Kopier-Schleifen.
Schritt 1: A nach C kopieren (PlÀtze 0,1,2)
Schritt 2: B ab Platz nA (=3) anhÀngen
Bevor wir den Code lesen: Was ist was? Wir haben drei Arrays und zwei ZĂ€hl-Variablen.
| Variable | Bedeutung | Wert |
|---|---|---|
| a | erstes Array | {1, 2, 3} |
| b | zweites Array | {4, 5} |
| c | Ergebnis-Array (noch leer) | [ ?, ?, ?, ?, ? ] |
| nA | n = anzahl, A = von Array a â wie viele Elemente in a | 3 |
| nB | n = anzahl, B = von Array b â wie viele Elemente in b | 2 |
#include <stdio.h>
int main()
{
int a[3] = {1, 2, 3}; // erstes Array
int b[2] = {4, 5}; // zweites Array
int c[5]; // Ergebnis, groĂ genug fĂŒr beide (3+2)
int nA = 3, nB = 2; // Anzahl: a hat 3, b hat 2 Elemente
/* Erst Array A kopieren */
for (int i = 0; i < nA; i++)
{
c[i] = a[i];
}
/* Dann Array B anhÀngen */
for (int i = 0; i < nB; i++)
{
c[nA + i] = b[i]; // Ab Position nA einfĂŒgen!
}
printf("ZusammengefĂŒhrt: ");
for (int i = 0; i < nA + nB; i++)
printf("%d ", c[i]);
return 0;
}
Nach dem Kopieren von A ist C schon halb gefĂŒllt:
B muss ab Position nA (=3) eingefĂŒgt werden!
| i (in B) | b[i] | nA + i | c[nA + i] |
|---|---|---|---|
| 0 | 4 | 3 + 0 = 3 | c[3] = 4 |
| 1 | 5 | 3 + 1 = 4 | c[4] = 5 |
#include <stdio.h>
int main()
{
int noten[10] = {2, 1, 3, 2, 1, 4, 2, 3, 5, 1};
int anzahl[6] = {0}; // ZĂ€hler fĂŒr Noten 1-5 (Index 0 ungenutzt)
/* Noten zÀhlen */
for (int i = 0; i < 10; i++)
{
anzahl[noten[i]]++;
}
/* Balkendiagramm ausgeben */
printf("Notenverteilung:\n");
for (int note = 1; note <= 5; note++)
{
printf("Note %d: ", note);
for (int j = 0; j < anzahl[note]; j++)
printf("*");
printf(" (%d)\n", anzahl[note]);
}
return 0;
}
Was ist das Zweithöchste in {5, 5, 3, 5}?
Das Maximum ist 5, das Zweithöchste ist 3.
Hmm, unser einfacher Algorithmus wĂŒrde zweit=5 liefern! đ€
Was ist h[3] nach diesem Code?
int arr[5] = {1, 3, 3, 2, 3};
int h[10] = {0};
for (int i = 0; i < 5; i++) h[arr[i]]++;
Die 3 kommt dreimal im Array vor!
A hat 4 Elemente, B hat 3 Elemente.
Wie groĂ muss Array C mindestens sein?
C muss Platz fĂŒr alle Elemente von A und B haben: 4 + 3 = 7
int max = arr[0], zweit = INT_MIN;
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
zweit = max; // Altes max â zweit
max = arr[i]; // Neues max
}
else if (arr[i] > zweit)
{
zweit = arr[i];
}
}
/* ZĂ€hler-Array fĂŒr Werte 0 bis MAX */
int haeufigkeit[MAX + 1] = {0};
for (int i = 0; i < n; i++)
{
haeufigkeit[arr[i]]++; // Wert als Index!
}
/* Verschachtelte Schleifen */
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++) // j startet bei i+1!
{
if (arr[i] == arr[j])
// Duplikat gefunden!
}
}
/* Erst A kopieren */
for (int i = 0; i < nA; i++)
c[i] = a[i];
/* Dann B anhÀngen */
for (int i = 0; i < nB; i++)
c[nA + i] = b[i]; // Ab Position nA!
| VL | Algorithmen | SchlĂŒsselkonzepte |
|---|---|---|
| 9 | Swap, Min, Max | temp Variable, Vergleich |
| 10 | Summe, ZĂ€hlen, Produkt | Akkumulator, Startwerte |
| 11 | Suche, Bubble Sort | break, verschachtelte Schleifen |
| 12 | Copy, Reverse, Shift, Palindrom | Zwei-Zeiger-Technik |
| 13 | 2nd Max, HĂ€ufigkeit, Duplikate, Merge | ZĂ€hler-Array, Paarvergleich |
Sie kennen jetzt die wichtigsten Algorithmen-Bausteine:
Zum Ăben und Nachschauen â besonders hilfreich: Werkzeuge, die Code Schritt fĂŒr Schritt sichtbar machen.