Einleitung Einleitung Gliederung Algorithmen und Datenstrukturen I Materialien zur Vorlesung 1 D. Rösner Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg Einleitung Begriffsbestimmung EUKLID Primzahltest c Winter 2009/10, 12. Oktober 2009, 2009/10 D.Rösner D. Rösner AuD I 2009/10 . . . Einleitung 1 D. Rösner AuD I 2009/10 . . . Begriffsbestimmung EUKLID Primzahltest Einleitung Eine wichtige Frage 2 Begriffsbestimmung EUKLID Primzahltest Algorithmus Frage: Was ist die wichtigste Fähigkeit, die in einem Studium der Informatik Algorithmus ist einer der zentralen Begriffe der Informatik Algorithmen: oder Wirtschaftsinformatik oder Computervisualistik oder Computer Systems Engineering/Ingenieurinformatik oder vergleichbarer Studiengänge gibt es auch unabhängig von Computern gibt es schon seit tausenden von Jahren Bezeichnung ’Algorithmus’ ist vom Namen des persischen Gelehrten Muhammed Al Chwarizimi (etwa 783 bis 850) abgeleitet (s.a. [PD08]) erworben und ausgebaut werden sollte? mögliche Antwort: Fähigkeit, für (viele) Probleme Lösungen finden zu können Problemlösungen dabei in Form von Algorithmen, die dann in ausführbare Programme umgesetzt D. Rösner AuD I 2009/10 . . . 4 D. Rösner AuD I 2009/10 . . . 5 Einleitung Begriffsbestimmung EUKLID Primzahltest Einleitung Algorithmus Begriffsbestimmung EUKLID Primzahltest Algorithmus Algorithmen (zumindest in einem intuitiven Sinne) begegnen uns auch im Alltag: eine intuitive Begriffsbestimmung für Algorithmus (vgl. [SS02]) Kochrezepte Bau- und Montageanleitungen Betriebsanleitungen ... Ein Algorithmus ist eine präzise (d.h. in einer festgelegten Sprache abgefasste) endliche Beschreibung eines allgemeinen Verfahrens unter Verwendung ausführbarer elementarer (Verarbeitungs-)Schritte. s.a. [SS02] D. Rösner AuD I 2009/10 . . . Einleitung 6 Begriffsbestimmung EUKLID Primzahltest D. Rösner AuD I 2009/10 . . . Einleitung EUKLIDs Algorithmus 7 Begriffsbestimmung EUKLID Primzahltest EUKLIDs Algorithmus Auf EUKLID (≈ 300 v. Chr.) geht ein Algorithmus zur Bestimmung des grössten gemeinsamen Teiler (ggT) zweier nicht negativer ganzer Zahlen zurück. Der ggT von x und y ist definiert als diejenige Zahl z, für die gilt: Eine Möglichkeit zum Bestimmen des ggT (x, y): Bestimme die Primfaktorzerlegung von x und die Primfaktorzerlegung von y und bilde das Produkt derjenigen Primfaktoren, die sowohl in der Faktorzerlegung von x als auch in der Faktorzerlegung von y vorkommen. z ist Teiler von x, z ist Teiler von y und für jedes z’ mit Beispiel: Bestimmung des ggT(12,42) ................................ ................................ ................................ z’ Teiler von x und z’ Teiler von y gilt: z’ ≤ z D. Rösner AuD I 2009/10 . . . 9 D. Rösner AuD I 2009/10 . . . 10 Einleitung Begriffsbestimmung EUKLID Primzahltest Einleitung EUKLIDs Algorithmus Begriffsbestimmung EUKLID Primzahltest EUKLIDs Algorithmus Fragen: Terminiert der Algorithmus immer? Warum? ................................ ................................ ................................ EUKLIDs Algorithmus ist ‘einfacher’ und eleganter. Er nutzt die folgenden Beziehungen: Wird immer der richtige Wert berechnet? ggT(x, y) = ggT(y, Rest von x/y) . . . falls y > 0 ggT(x, y) = x . . . falls y = 0 m.a.W.: Ist der Algorithmus korrekt? ................................ ................................ ................................ Hilft Testen beim Beantworten dieser Frage? ................................ ................................ ................................ D. Rösner AuD I 2009/10 . . . Einleitung 11 Begriffsbestimmung EUKLID Primzahltest D. Rösner AuD I 2009/10 . . . Einleitung EUKLIDs Algorithmus 12 Begriffsbestimmung EUKLID Primzahltest EUKLIDs Algorithmus eine mögliche Realisierung in Haskell: ggT :: Int -> Int -> Int ggT x y = if y > 0 then ggT y (rem x y) else if y == 0 then x else error "ggT: Argument y darf nicht negativ sein" Erläuterungen: ................................ ................................ ................................ D. Rösner AuD I 2009/10 . . . 13 einige Beispiele für Verwendung: Main> ggT 69 81 3 Main> ggT 43 101 1 Main> ggT 69 23 23 D. Rösner AuD I 2009/10 . . . 14 Einleitung Begriffsbestimmung EUKLID Primzahltest Einleitung EUKLIDs Algorithmus Algorithmus Primzahltest Primzahlen . . . z.B. wichtig für bestimmte Verschlüsselungsverfahren im folgenden werden Varianten eines Primzahltest entwickelt (s.a. [SS02], p. 65) zur Erinnerung: alternative Realisierung mit Wächtern (guards): ggT’ :: Int -> Int -> Int ggT’ | | | Begriffsbestimmung EUKLID Primzahltest x y y > 0 = ggT’ y (rem x y) y == 0 = x otherwise = error "ggT’: Argument y darf nicht negativ sein" Definition: Eine natürliche Zahl n (n > 1) ist genau dann Primzahl, wenn sie nur durch sich selbst und durch 1 teilbar ist. Bedingungen der Wächter werden nacheinander (von oben nach unten) überprüft Beispiele: prim oder nicht prim? 2 ist . . . 3 ist . . . alle geraden Zahlen grösser 2 sind . . . 31 ist . . . 51 ist . . . ... sobald eine erfüllt ist, wird ihre rechte Seite (nach =) ausgewertet und ergibt den Wert otherwise als letzter Wächter trifft immer zu (sog. catch all-Bedingung) D. Rösner AuD I 2009/10 . . . Einleitung 15 Begriffsbestimmung EUKLID Primzahltest D. Rösner AuD I 2009/10 . . . Einleitung Algorithmus Primzahltest 17 Begriffsbestimmung EUKLID Primzahltest Algorithmus Primzahltest erste Version des Algorithmus: erster Schritt: Um zu entscheiden, ob n > 1 Primzahl, teste, ob n durch irgendeine Zahl m mit 2 <= m < n teilbar. Wenn dies zutrifft, dann ist n nicht prim, andernfalls ist n prim. Test auf Teilbarkeit: istTeilerVon :: Int -> Int -> Bool istTeilerVon cand zahl = mod zahl cand == 0 realisiert mit einer Hilfsfunktion: istPrim :: Int -> Bool Beispiele für Verwendung: Main> 5 ‘istTeilerVon‘ 20 True Main> istTeilerVon 7 15 False Main> istTeilerVon 7 63 True D. Rösner AuD I 2009/10 . . . istPrim n = if n <= 1 then False else primtest 2 n primtest m n = if m >= n then True else if istTeilerVon m n then False else primtest (m + 1) n 18 D. Rösner AuD I 2009/10 . . . 19 Einleitung Begriffsbestimmung EUKLID Primzahltest Einleitung Algorithmus Primzahltest Begriffsbestimmung EUKLID Primzahltest Algorithmus Primzahltest Variante 2: Variante 1 funktioniert (d.h. ist effektiv), ist aber nicht effizient genug verbesserte Variante: istPrim’ :: Int -> Bool istPrim’ n = if n <= 1 || (n > 2 && istTeilerVon 2 n) then False else primtest 3 where primtest m = if m * m > n then True else if istTeilerVon m n then False else primtest (m + 2) Ziel: unnötigen Aufwand vermeiden es brauchen nur m = 2 und dann nur noch ungerade m getestet werden es braucht auch nicht bis m = n getestet zu werden, sondern es reicht zu testen, solange m*m <= n Mit beiden Veränderungen lässt sich der Aufwand deutlich verringern. Hinweis: primtest ist hier lokale Definition (nach where), d.h. nur innerhalb von istPrim’ sichtbar Motto (manchmal): Make it work, then make it fast! n ist innerhalb von primtest ’sichtbar’ und braucht daher nicht als Parameter übergeben zu werden D. Rösner AuD I 2009/10 . . . Einleitung D. Rösner AuD I 2009/10 . . . 20 Begriffsbestimmung EUKLID Primzahltest Einleitung Algorithmus Primzahltest 21 Begriffsbestimmung EUKLID Primzahltest Literatur: I weitere Variante: istPrim’’ :: Int -> Bool istPrim’’ n = if n <= 1 then False else primtest 2 where primtest m = if m * m > n then True else if istTeilerVon m n then False else primtest (if (m==2) then (m+1) else (m+2)) Hinweis: der letzte else-Zweig in primtest könnte gleichwertig auch wie folgt lauten: ... Gustav Pomberger and Heinz Dobler. Algorithmen und Datenstrukturen – Eine systematische Einführung in die Programmierung. Pearson Education Dtl. GmbH, München, 2008. Gunter Saake and Kai-Uwe Sattler. Algorithmen und Datenstrukturen – Eine Einführung mit Java. dpunkt.verlag, Heidelberg, 2002. ISBN 3-89864-122-8. else if istTeilerVon m n then False else if (m==2) then primtest (m+1) else primtest (m + 2) D. Rösner AuD I 2009/10 . . . 22 D. Rösner AuD I 2009/10 . . . 23