Einstieg in die Informatik mit Java Algorithmen Gerd Bohlender Institut für Angewandte und Numerische Mathematik 1 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 2 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 3 / 28 Überblick In diesem Kapitel werden Algorithmen und die Umsetzung einfacher Algorithmen in Java beschrieben. Algorithmus Genaue Vorschrift zur Berechnung / Bearbeitung eines Problems, z.B. Java-Programm Umsetzung in Java Darstellung des Algorithmus durch Befehle in Java 4 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 5 / 28 Algorithmus Präzise Beschreibung einer Berechnung oder allgemein eines Verfahrens. Benannt nach Muhammad al-Chwarizmi, ca. 780-850 in Persien. Deterministischer Algorithmus: ein Verfahren mit folgenden Eigenschaften • Das Verfahren muss durch einen endlichen Text oder eine endliche Grafik beschrieben werden (Finitheit) • Jeder Schritt des Verfahrens muss eindeutig ausführbar sein (Ausführbarkeit) • Der nächste anzuwendende Schritt des Verfahrens muss zu jedem Zeitpunkt eindeutig definiert sein (Determinismus) • Das Verfahren darf zu jedem Zeitpunkt nur endlich viel Speicherplatz benötigen (Dynamische Finitheit) • Das Verfahren muss nach endlich vielen Schritten enden (Terminierung) 6 / 28 Algorithmus: spezielle Varianten In manchen Fällen sind Ausnahmen sinnvoll: • Keine Terminierung: Mathematisches Iterationsverfahren: konvergiert gegen Lösung • Keine Terminierung: Betriebssystem eines Rechners • Keine Terminierung: Steuersoftware eines Geräts (z.B. Handy, Auto) oder Fertigungsprozess (z.B. in Chemiewerk) sollen dauerhaft laufen • Kein Determinismus: Verwendung einer (echten) Zufallszahl, unvorhersehbare zeitliche Abläufe in Parallelrechner 7 / 28 Beispiel zu Algorithmus: Euklidischer Algorithmus Berechne den größten gemeinsamen Teiler von zwei natürlichen Zahlen a und b. Euklid, ca. 360 v. Chr. (Athen) - 280 v. Chr. (Alexandria, heute Ägypten) 1 Solange b 6= 0 ist, wiederhole folgende Schritte 2 Berechne h = a mod b (Rest bei der Division) 3 Setze a = b 4 Setze b = h Dann ist a der ggT der ursprünglichen Zahlen. Ablauf am Beispiel a = 20, b = 24: a 20 24 20 4 b 24 20 4 0 h 20 4 0 – Der ggT von 20 und 24 ist 4. 8 / 28 Beispiel zu Algorithmus: Sieb des Eratosthenes Berechne alle Primzahlen bis zu einer gegebenen Zahl N > 1. Eratosthenes, ca. 276 v. Chr. (Kyrene, heute Libyen) bis 194 v. Chr. (Alexandria, heute Ägypten) 1 2 3 4 5 6 Erstelle Liste K ANDIDATEN aller ganzen Zahlen von 2 bis N Erstelle leere Liste P RIM der bereits erkannten Primzahlen Wiederhole folgende Schritte, bis die Liste K ANDIDATEN leer ist Bestimme die kleinste Zahl X in der Liste der K ANDIDATEN Füge X zur Liste P RIM hinzu Streiche X und alle seine ganzzahligen Vielfachen aus der Liste der K ANDIDATEN Ablauf am Beispiel N = 10: X 2 3 5 7 K ANDIDATEN 2, 3, 4, 5, 6, 7, 8, 9, 10 3, 5, 7, 9 5, 7 7 (leer) P RIM (leer) 2 2, 3 2, 3, 5 2, 3, 5, 7 9 / 28 Beispiel Roulette: Kein Algorithmus Fahre nach Baden-Baden und gewinne im Roulette 1 Beginne mit 1 Euro Einsatz 2 Wiederhole die folgenden Schritte bis Du eine Million Euro gewonnen hast 3 Setze den Einsatz auf rot oder schwarz 4 Falls Du gewinnst, kassiere den Gewinn und beginne wieder mit 1 Euro Einsatz 5 Falls Du verlierst, verdopple den Einsatz Kein Algorithmus: nicht determiniert, unbeschränkte Zwischenergebnisse. 10 / 28 Beispiel Roulette: Kein Algorithmus Ablauf, Anfangsguthaben 100 Euro: Einsatz 1 1 2 4 8 16 ... Gewinn 1 0 0 0 0 16 Guthaben 101 100 98 94 86 102 Theoretisch steigt das Guthaben nach jeder Verdoppelungsphase um 1 Euro Praktisch funktioniert dies so nicht, da zwischenzeitliche Verluste beliebig groß werden können. Auftreten von Zero und weitere Regeln der Spielbank (z.B. Mindest- und Höchsteinsatz) sind zu beachten. 11 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 12 / 28 Grundalgorithmen in Java Die wichtgsten Anweisungen in Java: • Wertzuweisung: Variable erhält den Wert der rechten Seite x = 27; y = 3∗x + 2 ; • Eingabeanweisung: Variable erhält einen eingelesenen Wert i = sc . n e x t I n t ( ) ; x = sc . nextDouble ( ) ; • Ausgabeanweisung: der Wert wird ausgegeben System . o u t . p r i n t l n ( ” B i t t e x eingeben : ” ) ; System . o u t . p r i n t l n ( y ) ; System . o u t . p r i n t l n ( ” Ergebnis = ” + y ) ; Alle verwendeten Variablen müssen zuvor definiert werden, z.B int i , j , k ; double x , y ; 13 / 28 Grundstruktur eines Java-Programms Der typische Aufbau eines Java-Programms import j a v a . u t i l . ∗ ; public class ProgrammName { public s t a t i c void main ( S t r i n g [ ] args ) { Locale . s e t D e f a u l t ( Locale .US ) ; Scanner sc = new Scanner ( System . i n ) ; / / h i e r werden d i e b e n ö t i g t e n / / Variablen d e f i n i e r t / / h i e r s t e h t der A l g o r i t h m u s des Programms / / ( Folge von Anweisungen ) } } 14 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 15 / 28 Flussdiagramme Kompliziertere Algorithmen müssen formal beschrieben werden. • Flussdiagramme / Programmablaufpläne • Anweisungen in Rechtecken / Rauten / Parallelogrammen • Reihenfolge der Anweisungen wird mit Pfeilen angezeigt • in DIN 66001 genormt • kann unübersichtlich werden • schwierig zu bearbeiten 16 / 28 Flussdiagramm: Gib 1 bis 39 und 61 bis 100 aus Quelle: de.wikipedia.org/wiki/Programmablaufplan 17 / 28 Gliederung 1 Überblick 2 Algorithmus 3 Grundalgorithmen in Java 4 Flussdiagramme 5 Struktogramme 18 / 28 Struktogramme Kompliziertere Algorithmen müssen formal beschrieben werden. • Flussdiagramme oft unübersichtlich und unstrukturiert • Alternative: Struktogramme / Nassi-Shneiderman-Diagramme • Rechteckige Kästen enthalten elementare Anweisungen • Die Kästen können aneinander gereiht und geschachtelt werden • von Isaac Nassi und Ben Shneiderman entwickelt (1972/73, USA) • in DIN 66261 genormt • Weitere Alternative: UML (Unified Modeling Language) Quelle der folgenden Grafiken: de.wikipedia.org/wiki/Nassi-Shneiderman-Diagramm 19 / 28 Folge von Anweisungen Mehrere Anweisungen sollen in der angegebenen Reihenfolge ausgeführt Darstellung in Java: { Anweisung1 Anweisung2 Anweisungn } 20 / 28 Einfache Auswahl von Anweisungen Abhängig von einer Bedingung sollen Anweisungen ausgeführt werden oder nicht Darstellung in Java: i f ( Bedingung ) { Anweisung1 Anweisung2 Anweisungn } 21 / 28 Zweiseitige Auswahl von Anweisungen Abhängig von einer Bedingung sollen Anweisungen ausgeführt werden oder andere Anweisungen Darstellung in Java: i f ( Bedingung ) { Anweisung1 . 1 Anweisung1 . 2 Anweisung1 . n } else { Anweisung2 . 1 Anweisung2 . 2 Anweisung2 . n } 22 / 28 Wiederholung von Anweisungen Anweisungen soll mehrfach ausgeführt werden Darstellung in Java: f o r ( i n t i = S t a r t w e r t ; i <=Endwert ; i ++) { Anweisung1 Anweisung2 Anweisungn } 23 / 28 Wiederholung von Anweisungen Solange eine Bedingung erfüllt ist, sollen Anweisungen wiederholt werden; die Bedingung soll zuerst geprüft werden Darstellung in Java: while ( Bedingung ) { Anweisung1 Anweisung2 Anweisungn } 24 / 28 Wiederholung von Anweisungen Solange eine Bedingung erfüllt ist, sollen Anweisungen wiederholt werden; die Bedingung soll erst nachträglich geprüft werden Darstellung in Java: do { Anweisung1 Anweisung2 Anweisungn } while ( Bedingung ) ; 25 / 28 Auswahl von Anweisungen Je nach Wert eines Ausdrucks sollen unterschiedliche Anweisungen ausgeführt werden Darstellung in Java: switch ( Ausdruck ) { Wert1 : Anweisungen1 Wert2 : Anweisungen2 Wert3 : Anweisungen3 Wertn : Anweisungenn default : AlternativAnweisungen } 26 / 28 Aufruf einer Methode Rufe eine Methode auf (berechne Funktion, führe Zwischenrechnung aus) Darstellung in Java: nameDerMethode ( Parameter ) 27 / 28 Zusammensetzung geschachtelter Anweisungen Berechne den ggT zweier Zahlen, nur mit Subtraktionen Darstellung in Java: while ( a>0 && b>0) { if (a > b) { a = a−b ; } else { b = b−a ; } } i f ( b == 0 ) { System . o u t . p r i n t l n ( a ) ; } else { System . o u t . p r i n t l n ( b ) ; } 28 / 28