In der Serie "Named Problems" stelle ich dir klassische, namentlich bekannte Algorithmus-Probleme vor, die seit Jahrzehnten in Ausbildung, Studium und Interviews verwendet werden. Anhand verständlicher Problemstellungen wie FizzBuzz, Türme von Hanoi oder dem Sieb des Eratosthenes lernst du hier, algorithmisch zu denken, Lösungsstrategien zu entwickeln und diese sauber in Java umzusetzen.
FizzBuzz ist ein klassisches Einstiegsproblem aus Interviews, Übungen und Coding-Katas. Es ist so bekannt, weil es auf den ersten Blick simpel wirkt, aber genau die Basics prüft, die du ständig brauchst: Kontrollfluss und Bedingungen.
Du lernst hier, wie du Regeln sauber in if-Abfragen übersetzt, warum die Reihenfolge der Bedingungen wichtig ist, und wie dir der %-Operator (Modulo) dabei hilft.
Ausserdem schauen wir uns zwei Java-Varianten an: erst eine straightforward Lösung, dann eine Alternative, die besser strukturiert ist und sich leichter erweitern laesst.
Problemstellung
Schreibe ein Programm, das Zahlen von 1 bis n durchläuft und je nach Teilbarkeit unterschiedliche Ausgaben macht.
- Wenn die Zahl durch 3 teilbar ist: gib
Fizzaus - Wenn die Zahl durch 5 teilbar ist: gib
Buzzaus - Wenn die Zahl durch 3 und 5 teilbar ist: gib
FizzBuzzaus - Sonst: gib die Zahl selbst aus
Mini-Beispiel (für n = 15):
1->13->Fizz5->Buzz15->FizzBuzz
Die Idee dahinter
Das Kernkonzept ist: Wir prüfen pro Zahl Bedingungen und entscheiden danach, was gedruckt wird. Teilbarkeit prüfst du in Java am einfachsten mit n % k == 0.
Modulo gibt dir den Rest einer Division. Wenn der Rest 0 ist, ist die Zahl ohne Rest teilbar.
6 % 3 == 0(teilbar)7 % 3 == 1(nicht teilbar)
Wichtig ist ausserdem die Reihenfolge: FizzBuzz muss zuerst kommen, sonst greift schon Fizz oder Buzz und du erreichst den kombinierten Fall nie.
Schritt für Schritt zur Lösung
-
Schleife festlegen:
Laufe von1bisn(inklusive). -
Teilbarkeit pruüen:
Nutze%, um Teilbarkeit durch3und5zu prüfen. -
Reihenfolge beachten:
Prüfe zuerst3und5zusammen. -
Ausgabe wählen:
Gib je nach FallFizzBuzz,Fizz,Buzzoder die Zahl aus. -
Testen:
Probiere kleine Werte wien = 5odern = 15, um alle Fälle zu sehen.
Java-Implementierung (Variante A: straightforward)
public class FizzBuzzStraightforward {
public static void main(String[] args) {
printFizzBuzzUpTo(15);
}
static void printFizzBuzzUpTo(int n) {
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
}
}
Diese Variante ist direkt und gut lesbar: eine Schleife, dann eine if-Kette. Der wichtigste Punkt ist die erste Bedingung i % 3 == 0 && i % 5 == 0, weil sie den kombinierten Fall abfängt. Für Einsteiger ist das oft die beste erste Lösung, weil man den Ablauf sofort erkennt.
Java-Implementierung (Variante B: Alternative oder Verbesserung)
public class FizzBuzzAlternative {
public static void main(String[] args) {
printFizzBuzzUpTo(15);
}
static void printFizzBuzzUpTo(int n) {
for (int i = 1; i <= n; i++) {
System.out.println(toFizzBuzzValue(i));
}
}
static String toFizzBuzzValue(int number) {
String result = "";
if (isDivisibleBy(number, 3)) {
result += "Fizz";
}
if (isDivisibleBy(number, 5)) {
result += "Buzz";
}
if (result.isEmpty()) {
return String.valueOf(number);
}
return result;
}
static boolean isDivisibleBy(int number, int divisor) {
return number % divisor == 0;
}
}
Hier wird die Logik in kleine Methoden aufgeteilt: toFizzBuzzValue liefert den Text für eine Zahl, und isDivisibleBy kapselt die Teilbarkeitsprüfung. Das wirkt erst mal länger, ist aber oft besser wartbar: Wenn du später neue Regeln hinzufügen willst (z.B. für 7), ist das deutlich einfacher. Ausserdem vermeidest du eine lange else if-Kette und baust das Ergebnis schrittweise auf.
Beispiel: Eingabe und Ausgabe
Beispiel 1: Eingabe n = 5, Ausgabe (zeilenweise): 1, 2, Fizz, 4, Buzz
Beispiel 2: Eingabe n = 15, Ausgabe fuer die letzten Zeilen: 13, 14, FizzBuzz
Beispiel 3: Eingabe n = 3, Ausgabe: 1, 2, Fizz
Typische Fehler
-
Falsche Reihenfolge der Bedingungen:
Wenn du ersti % 3 == 0prüfst, kommtFizzBuzznie, weil15schon beiFizzlandet. -
Off-by-one in der Schleife:
i < nstatti <= nlässt die letzte Zahl weg. -
Modulo falsch verstanden:
i % 3 == 1ist keine Teilbarkeitsprüfung, sondern ein konkreter Restwert. -
Mehrere
ifohne Abstimmung:
Wenn du in Variante A stattelse ifmehrere einzelneifnutzt, kann es zu Mehrfachausgaben pro Zahl kommen. -
String-Aufbau unklar: In Variante B vergessen viele
result.isEmpty()und geben dann bei normalen Zahlen eine leere Zeile aus. -
Magische Zahlen überall:
Wenn3und5hart verteilt stehen, wird Erweitern und Testen nervig. Kapsel es wenigstens in eine Methode wieisDivisibleBy.
Fazit
Mit FizzBuzz übst du die Grundlagen, die in fast jedem Programm vorkommen: Iteration, saubere Bedingungen und den Einsatz von % für Teilbarkeit. Du hast gesehen, warum die Reihenfolge der Checks wichtig ist und wie man Logik entweder direkt (Variante A) oder besser strukturiert (Variante B) umsetzen kann.
Die Laufzeit ist hier linear: pro Zahl machst du ein paar konstante Checks. Wenn du das Problem erweiterst (mehr Regeln), lohnt es sich, die Regeln als Daten zu modellieren (z.B. Liste von Teilern und Texten) und die Ausgabe daraus zusammenzubauen. Damit bleibt dein Kontrollfluss stabil, auch wenn neue Fälle dazukommen.
