Grundlagen der Programmierung
💡 Alle nutzen bekannte Konzepte: Schleifen, Arrays, Swap, Vergleiche
Manchmal brauchen wir eine Kopie eines Arrays:
int original[5] = {1, 2, 3, 4, 5}; int kopie[5]; kopie = original; // ❌ FEHLER! Arrays können nicht so kopiert werden!
Wir müssen jedes Element einzeln kopieren:
#include <stdio.h> int main() { int original[5] = {10, 20, 30, 40, 50}; int kopie[5]; /* Element für Element kopieren */ for (int i = 0; i < 5; i++) { kopie[i] = original[i]; } /* Kopie verändern - Original bleibt unverändert! */ kopie[0] = 999; printf("Original[0]: %d\n", original[0]); // 10 printf("Kopie[0]: %d\n", kopie[0]); // 999 return 0; }
Original:
⬇️ kopiere jedes Element ⬇️
Kopie:
kopie[i] = original[i] für alle i
Aufgabe: Die Reihenfolge der Elemente umdrehen
Vorher:
🔄
Nachher:
Idee: Zwei Index-Variablen ("Zeiger") - einer am Anfang, einer am Ende
left und rightleft++, right--left >= rightleft=0, right=4: Tausche arr[0] ↔ arr[4]
left=1, right=3: Tausche arr[1] ↔ arr[3]
left=2, right=2: left >= right → FERTIG!
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int n = 5; int left = 0; int right = n - 1; int temp; while (left < right) { /* Swap arr[left] und arr[right] */ temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; // Nach rechts bewegen right--; // Nach links bewegen } printf("Umgekehrt: %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]); return 0; }
left < right?left=0, right=3 → Tausch
left=1, right=2 → Tausch
left=2, right=1 → STOP (2 > 1)
left=0, right=4 → Tausch
left=1, right=3 → Tausch
left=2, right=2 → STOP (gleich!)
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int n = 5; int temp; /* Nur bis zur Mitte iterieren! */ for (int i = 0; i < n / 2; i++) { /* Tausche arr[i] mit arr[n-1-i] */ temp = arr[i]; arr[i] = arr[n - 1 - i]; arr[n - 1 - i] = temp; } printf("Umgekehrt: %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]); return 0; }
n - 1 - i ist der "gespiegelte" Index
n - 1 - i?
Formel: gespiegelter_index = n - 1 - i
Bei n = 5 (Array mit 5 Elementen):
| i | n - 1 - i | Rechnung | Tausch |
|---|---|---|---|
| 0 | 4 | 5 - 1 - 0 = 4 | arr[0] ↔ arr[4] |
| 1 | 3 | 5 - 1 - 1 = 3 | arr[1] ↔ arr[3] |
| 2 | 2 | 5 - 1 - 2 = 2 | Mitte (kein Tausch) |
i von links nach rechts läuft, läuft n-1-i automatisch von rechts nach links!
Alle Elemente nach links
⬇️
Alle Elemente nach rechts
⬇️
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int n = 5; /* Erstes Element sichern (geht sonst verloren) */ int erstes = arr[0]; /* Alle Elemente nach links verschieben */ for (int i = 0; i < n - 1; i++) { arr[i] = arr[i + 1]; // Kopiere rechten Nachbarn } /* Optional: Erstes Element ans Ende (Rotation) */ arr[n - 1] = erstes; printf("Nach Shift Left: %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]); return 0; }
Array: {1, 2, 3, 4, 5} → erstes = 1
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 4, 5}; int n = 5; /* Letztes Element sichern */ int letztes = arr[n - 1]; /* Von HINTEN nach vorne verschieben! */ for (int i = n - 1; i > 0; i--) { arr[i] = arr[i - 1]; // Kopiere linken Nachbarn } /* Optional: Letztes Element an den Anfang (Rotation) */ arr[0] = letztes; printf("Nach Shift Right: %d %d %d %d %d\n", arr[0], arr[1], arr[2], arr[3], arr[4]); return 0; }
for (i = 0; i < n-1; i++) arr[i+1] = arr[i];
{1,2,3,4,5} → {1,1,1,1,1}
Wert wird überschrieben bevor kopiert!
for (i = n-1; i > 0; i--) arr[i] = arr[i-1];
{1,2,3,4,5} → {?,1,2,3,4}
Jeder Wert wird kopiert bevor überschrieben!
Ein Palindrom liest sich vorwärts und rückwärts gleich!
Es geht nicht nur um Palindrome! Die Technik dahinter ist das Wichtige:
Palindrom-Aufgaben sind sehr beliebt in Bewerbungsgesprächen bei Tech-Firmen (Google, Amazon, etc.) - sie testen Ihr Verständnis der Zwei-Zeiger-Technik!
Wieder die Zwei-Zeiger-Technik!
left++, right--, weiterleft >= right → Ist ein Palindrom!Prüfe: {1, 2, 3, 2, 1}
Prüfe: {1, 2, 3, 4, 1}
#include <stdio.h> int main() { int arr[5] = {1, 2, 3, 2, 1}; int n = 5; int left = 0; int right = n - 1; int istPalindrom = 1; // Annahme: ist Palindrom while (left < right) { if (arr[left] != arr[right]) { istPalindrom = 0; // Kein Palindrom! break; } left++; right--; } if (istPalindrom) printf("Ist ein Palindrom!\n"); else printf("Kein Palindrom.\n"); return 0; }
while (left < right) { /* TAUSCHEN */ temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; right--; }
Aktion: Elemente tauschen
while (left < right) { /* VERGLEICHEN */ if (arr[left] != arr[right]) { istPalindrom = 0; break; } left++; right--; }
Aktion: Elemente vergleichen
Was gibt dieser Code aus?
int a[3] = {1, 2, 3}; int b[3]; for (int i = 0; i < 3; i++) b[i] = a[i]; a[0] = 99; printf("%d", b[0]);
A) 99
B) 1
C) 0
D) Fehler
b ist eine echte Kopie - Änderungen an a beeinflussen b nicht!
Wie viele Swaps braucht man, um ein Array mit 6 Elementen umzukehren?
A) 6
B) 5
C) 3
D) 2
Wir tauschen nur bis zur Mitte: n/2 = 6/2 = 3 Swaps
→ {F, E, D, C, B, A} ✓
Welches Array ist ein Palindrom?
A) {1, 2, 3, 4, 5}
B) {5, 4, 3, 4, 5}
C) {1, 2, 2, 1, 1}
D) {3, 3, 3}
/* Array kopieren */ for (int i = 0; i < n; i++) { kopie[i] = original[i]; }
kopie = original funktioniert NICHT!/* Array umkehren mit Zwei-Zeiger-Technik */ int left = 0, right = n - 1; while (left < right) { /* Swap */ int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; right--; }
int erstes = arr[0]; for (i = 0; i < n-1; i++) arr[i] = arr[i+1]; arr[n-1] = erstes; // optional
Von vorne nach hinten (i++)
int letztes = arr[n-1]; for (i = n-1; i > 0; i--) arr[i] = arr[i-1]; arr[0] = letztes; // optional
Von hinten nach vorne (i--)
/* Palindrom prüfen */ int left = 0, right = n - 1, istPalindrom = 1; while (left < right) { if (arr[left] != arr[right]) { istPalindrom = 0; break; } left++; right--; }