Letzte Woche Universität Paderborn Prof. Dr. Heike Wehrheim For-Schleifen Syntax: for (Initialisierung; Bedingung; Fortschaltung) Schleifenrumpf Bedeutung: 1. am Anfang Initialisierung 2. dann Prüfung der Bedingung falls wahr, Ausführung Schleifenrumpf; Fortschaltung; weiter mit 2 falls falsch, weiter hinter Schleife GPI, WS 07/08 162 Aufgabe Universität Paderborn Prof. Dr. Heike Wehrheim for (int i = 10; i > 0; i = i - 2) System.out.print(i); … gibt aus a) 10 9 8 7 6 5 4 3 2 1 b) 8 6 4 2 0 c) 8 6 4 2 d) 10 8 6 4 2 0 e) 10 8 6 4 2 GPI, WS 07/08 163 Weitere Schleifenart Universität Paderborn Prof. Dr. Heike Wehrheim For-Schleifen wiederholen Anweisungen eine bestimmte Anzahl oft. Weitere Art von Schleifen: Wiederholen solange/bis eine gewisse Bedingung gilt -> While Schleifen GPI, WS 07/08 164 While-Schleifen Universität Paderborn Prof. Dr. Heike Wehrheim while (Bedingung) Anweisung Solange die Auswertung der Bedingung wahr ergibt, wird die Anweisung ausgeführt. Reihenfolge: Testen der Bedingung, true? → Anweisung ausführen → Testen der Bedingung, true? → Anweisung ausführen → .... Testen der Bedingung, true? → Anweisung ausführen → Testen der Bedingung, false? → weiter hinter der while-Schleife GPI, WS 07/08 165 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Aufgabenbeschreibung: Eingabe: eine positive ganze Zahl n Ausgabe: Summe der Zahlen von 1 bis n Algorithmus: lese n ein setze zähler und summe auf 0 solange zähler < n erhöhe zähler um 1 addiere zähler zu summe dazu gib summe aus GPI, WS 07/08 166 In Java Universität Paderborn Prof. Dr. Heike Wehrheim int n = Integer.parseInt(args[0]); int zaehler = 0; Was passiert, wenn hier zaehler <= n steht? int summe = 0; while (zaehler < n) { zaehler++; summe += zaehler; } System.out.println(summe); GPI, WS 07/08 167 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Berechnung des größten gemeinsamen Teilers (GGT) zweier positiver Zahlen int a, b; ... // Definition der Inhalte von a und b while (a != b) { if (a > b) a = a - b; else b = b - a; } System.out.println(a); Terminiert diese Schleife bei allen int-Eingabewerten? GPI, WS 07/08 168 Universität Paderborn Prof. Dr. Heike Wehrheim Jedes For als While? Beispiel: Beide Schleifen sind im Verhalten äquivalent. for (int i=1; i<10000; i++) { //Tue irgendwas } int i=1; while (i<10000) { //Tue irgendwas i++; } Die kontrollierenden Anteile stehen bei for gruppiert, bei while isoliert. Jedes While als For? Nein (zumindest nicht schön) GPI, WS 07/08 169 Universität Paderborn Prof. Dr. Heike Wehrheim Beispiel Collatzfolge Collatzfolge: Folge von Zahlen z_0, z_1, z_2, …, die gemäss folgenden Regeln gebildet wird: 1. Wähle einen positiven Startwert z_0 2. Ist z_n gerade, dann ist z_n+1 = z_n / 2 3. Ist z_n ungerade, dann ist z_n+1 = 3 * z_n + 1 Beispiel: z_0 = 6 6 3 10 5 16 8 4 2 1 4 2 1 4 2 1 … Beobachtung: egal, welcher Startwert, am Ende immer 4 2 1 4 2 1 … (aus: Schiedermeier) GPI, WS 07/08 170 Collatzfolge Universität Paderborn Prof. Dr. Heike Wehrheim Aufgabenbeschreibung: Eingabe: Startwert n Ausgabe: Collatzfolge bis zu erstem Auftreten von 1 Algorithmus: lese n ein gebe n aus solange n ungleich 1 falls n gerade dann setze n auf n / 2 sonst setze n auf 3 * n + 1 gebe n aus GPI, WS 07/08 171 In Java Universität Paderborn Prof. Dr. Heike Wehrheim int n = Integer.parseInt(args[0]); System.out.println(n); while (n!=1) { if (n%2 == 0) n = n / 2; else n = 3 * n + 1; System.out.println(n); } GPI, WS 07/08 172 Nun Erweiterungen Universität Paderborn Prof. Dr. Heike Wehrheim 1. Erweiterung: Länge der Folge zählen int n = Integer.parseInt(args[0]); System.out.println(n); int zaehler = 1; while (n!=1) { if (n%2 == 0) n = n / 2; else n = 3 * n + 1; System.out.println(n); zaehler++; } System.out.println(“Laenge der Folge: “ + zaehler); GPI, WS 07/08 173 2. Erweiterung Universität Paderborn Prof. Dr. Heike Wehrheim 2. Erweiterung: Maximalwert ermitteln Collatzfolge.java int n = Integer.parseInt(args[0]); System.out.println(n); int zaehler = 1; int max = n; while (n!=1) { if (n%2 == 0) n = n / 2; else n = 3 * n + 1; System.out.println(n); zaehler++; if (n > max) max = n; } System.out.println("Laenge: " + zaehler); System.out.println("Maximalwert: " + max); GPI, WS 07/08 174 Variante: do-while Universität Paderborn Prof. Dr. Heike Wehrheim do Anweisung while (Bedingung); Die Anweisung wird einmal ausgeführt und danach solange wiederholt, wie die Bedingung wahr liefert. Reihenfolge: Anweisung ausführen → Testen der Bedingung, true? → Anweisung ausführen → .... Testen der Bedingung, true? → Anweisung ausführen → Testen der Bedingung, false? → weiter hinter der do-while-Schleife GPI, WS 07/08 175 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Countdown int zaehler = 10; do { System.out.println(zaehler); zaehler--; } while (zaehler >= 0); /* weitermachen, solange noch nicht über 0 hinaus */ GPI, WS 07/08 176 Wichtig! Universität Paderborn Prof. Dr. Heike Wehrheim Bedingungen in der Schleife müssen initialisiert werden Falsch: esRegnet nicht initialisiert (Compiler meldet Fehler) Beispiel: boolean esRegnet; while (! esRegnet) System.out.println(“ich gehe spazieren“); GPI, WS 07/08 177 Wichtig! Universität Paderborn Prof. Dr. Heike Wehrheim Terminierung der Schleife muß garantiert werden Beispiel: Falsch: Schleife findet kein Ende int zahl = 1; while (zahl > 0) { System.out.println(zahl); } GPI, WS 07/08 178 Weiteres Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Aufgabenbeschreibung: Berechnung der FibonacciZahlen bis Wert 50 1 1 2 3 5 8 13 21 … (Elemente jeweils Summe der beiden vorherigen) Algorithmus: setze 1 als letzten und 1 als aktuellen Wert; gebe letzten Wert aus; solange aktueller Wert kleiner gleich 50 gebe aktuellen Wert aus; setze aktuellen Wert auf Summe des aktuellen und des letzten; setze letzten Wert auf vorherigen aktuellen; GPI, WS 07/08 179 In Java Universität Paderborn Prof. Dr. Heike Wehrheim class Fibonacci { // Ausgabe der Fibonacci Zahlen bis 50 public int int int static void main(String [] args) { letzterWert = 1; aktuellerWert = 1; hilfe; System.out.println(letzterWert); while (aktuellerWert <= 50) { System.out.println(aktuellerWert); hilfe = aktuellerWert; aktuellerWert += letzterWert; letzterWert = hilfe; }}} GPI, WS 07/08 vorheriger aktueller 180 Anwendungsmuster Universität Paderborn Prof. Dr. Heike Wehrheim Typische Anwendungsmuster für Schleifen Iterationen zählen Iterieren bis Zielbedingung gilt Suchschleife (kommt später, Arrays) GPI, WS 07/08 181 Iterationen zählen Universität Paderborn Prof. Dr. Heike Wehrheim Eine Variable zählt die Ausführungen des Schleifenrumpfes mit. Varianten: Aufwärts oder abwärts zählen Versetzt zählen, mit Startwert != 0 Mit Schrittweite != 1 zählen (gerade bei Collatzfolge gesehen) GPI, WS 07/08 182 Iterieren bis Zielbedingung Universität Paderborn Prof. Dr. Heike Wehrheim Ziel: nach Abschluss der Iteration gilt eine gewisse Zielbedingung Zielbedingung wird logisch in 2 Teile zerlegt: Inv and Halt Inv gilt vor, während und nach der Schleife Negation von Halt wird Schleifenbedingung GPI, WS 07/08 183 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Binärdarstellung einer Zahl berechnen Methode: iterativ durch 2 dividieren und Reste aufschreiben Invariante: “binärdarstellung(zahl)“ + ergebnis = binärdarstellung(anfangswert von zahl) Halt: zahl = 0 class Dec2Bin { public static void main (String [] args) { Aneinanderhängen int zahl = Integer.parseInt(args[0]); von Zeichenketten String ergebnis = ""; while (zahl != 0) { ergebnis = Integer.toString(zahl%2) + ergebnis; zahl = zahl / 2; }; System.out.println(ergebnis); }} Zahl in Zeichenkette umwandeln GPI, WS 07/08 184 For oder While? Universität Paderborn Prof. Dr. Heike Wehrheim Bei der Entscheidung, ob For oder While benutzt wird, kann folgende Frage helfen: Kenne ich (1) die Anzahl der Durchläufe (in Abhängigkeit von Variablenwerten) oder kenne ich (2) nur eine Abbruchbedingung für die Iteration? (1) For-Schleife (2) While-Schleife GPI, WS 07/08 185 Beispiele Universität Paderborn Prof. Dr. Heike Wehrheim Collatzfolge: Abbruch, wenn 1 erreicht ist was für eine Schleife? Fibonacci-Folge: Abbruch, wenn 50 erreicht ist was für eine Schleife? Aufsummieren der ersten n Zahlen was für eine Schleife? GGT: Abbruch, wenn a = b ist was für eine Schleife? Zeichnen eines 5 x 5 Sternequadrats was für eine Schleife? GPI, WS 07/08 186 In Abschnitt 1.3 gelernt Universität Paderborn Prof. Dr. Heike Wehrheim Bedingte Anweisungen: if (mit und ohne else) switch Benutzung von Blöcken in then- und else-Teil Schachtelung von IFs Wiederholungen for while Geschachtelte Schleifen Zusammenhang for – while Schleifen in IFs, IFs in Schleifen GPI, WS 07/08 187 Fragen Universität Paderborn Prof. Dr. Heike Wehrheim 1. Wie verhält sich die folgende for-Schleife? a) for (int i = 0; i < i+1; i--;) b) for (int i = 0; i < 10; i++) i--; 2. Welchen Wert hat i (Anfangswert 0) am Ende der Iteration? a) int j = 0; while (j < 10) { j++; i--; } b) int j = 0; do { j++; i--; } while (j < 10) GPI, WS 07/08 188 Noch ein Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Aufgabenbeschreibung: Ein Programm schreiben, das ausrechnet, wieviele Jahre man sparen muss bis man 1000 Euro besitzt, wenn man mit 100 Euro startet und die Bank einen Zinssatz von 5% anbietet. Welche Art von Schleife, For oder While? GPI, WS 07/08 189 In Java Universität Paderborn Prof. Dr. Heike Wehrheim public static void main (String [] args) { double kapital = 100.0; int zinssatz = 5; int zaehler = 0; do { kapital += kapital * (zinssatz / 100.0); zaehler++; } while (kapital < 1000.0); System.out.print("Nach " + zaehler); System.out.println(" Jahren hat man ein Kapital von " + kapital + " Euro."); } Anwendungsmuster: Schleifendurchläufe zählen GPI, WS 07/08 190