Funktionale Programmierung ALP I Funktionale Programmierung … weiter mit Listen SS 2011 Prof. Dr. Margarita Esponda Prof. Dr. Margarita Esponda Funktionale Programmierung Aufgabe: Überprüfung der Klammersetzung Mit Hilfe eines Stapels (Liste) soll ein Haskell-Programm geschrieben werden, das einen Text liest und kontrolliert, ob alle Arten von Klammern richtig gesetzt sind. { [ ( ( ) [] )]} Stapel Prof. Dr. Margarita Esponda Funktionale Programmierung Listen als Stapel push Stapel { Prof. Dr. Margarita Esponda [ ( ( ) [ ] )] } Funktionale Programmierung Listen als Stapel push Stapel [ { Prof. Dr. Margarita Esponda ( ( ) [ ] )] } Funktionale Programmierung Listen als Stapel ( ) [ ] )] } push Stapel ( [ { Prof. Dr. Margarita Esponda Funktionale Programmierung Listen als Stapel ) [ ] )] } push Stapel ( ( [ { Prof. Dr. Margarita Esponda Funktionale Programmierung Listen als Stapel [ ] )] } pop Stapel ( [ { Prof. Dr. Margarita Esponda ( Funktionale Programmierung Listen als Stapel ] )] } push Stapel [ ( [ { Prof. Dr. Margarita Esponda Funktionale Programmierung Listen als Stapel )] } pop Stapel ( [ { Prof. Dr. Margarita Esponda [ Funktionale Programmierung Listen als Stapel ]} pop Stapel [ { Prof. Dr. Margarita Esponda ( Funktionale Programmierung Listen als Stapel } pop Stapel [ { Prof. Dr. Margarita Esponda Funktionale Programmierung Listen als Stapel Die Klammersetzung war richtig! pop Stapel { Prof. Dr. Margarita Esponda Funktionale Programmierung [ ] )] } Stapel ( [ { Prof. Dr. Margarita Esponda Wenn am Ende der Eingabe der Stapel leer ist, dann war die Klammersetzung richtig. Funktionale Programmierung Listen als Stapel Falsche Klammersetzung 1. Fall 2. Fall ] 3. Fall { ...] { ... Ende falsche rechte Klammer leer Der Stapel ist leer und eine schließende Klammer wird gelesen. Prof. Dr. Margarita Esponda { nicht leer { Der Stapel ist am Ende nicht leer. Funktionale Programmierung Listen als Stapel balanced:: [Char ] -> Bool balanced ls = bal [] ls bal:: [Char] -> [Char] -> Bool bal [] [] = True bal s ('(':xs) = bal ('(':s) xs bal s ('[':xs) = bal ('[':s) xs bal s ('{':xs) = bal ('{':s) xs bal ('(':xs) (')':ys) = bal xs ys bal ('[':xs) (']':ys) = bal xs ys bal ('{':xs) ('}':ys) = bal xs ys bal Prof. Dr. Margarita Esponda _ _ = False Funktionale Programmierung … weiter mit Listen random :: Int -> Int random seed = (25173*seed + 13849) `mod` 65536 randList n = randList' n [] randList' n xs | (length xs) == n = xs | otherwise = randList' n (a:xs) where a = random (head xs) Prof. Dr. Margarita Esponda Funktionale Programmierung Arithmetische Sequenzen Mit Hilfe des .. Operators lassen sich in Haskell sehr elegant Zahlensequenzen erzeugen. [ 1 .. 5 ] => [1,2,3,4,5] [ 0, 5 .. 21] => [ 0, 5, 10, 15, 20 ] [ 10, 8 .. 0 ] => [ 10, 8, 6, 4, 2, 0 ] [ 10 .. 1 ] => [] [ 1 .. ] => unendliche Liste take 5 [2, 0 .. ] => [ 2, 0, -2, -4, -6 ] … Prof. Dr. Margarita Esponda Funktionale Programmierung Listen-Generatoren Die Syntax von Listengeneratoren in Haskell ist sehr ähnlich zu dem, was wir für die Definition von Mengen in der Mathematik kennen. Mathematik: { x ∈ { 1 .. 20 } | x mod 3 = 0 } Menge aller Zahlen, die genau durch 3 geteilt werden können Haskell: [ x | x <- [1 .. 20], mod x 3 == 0 ] damit gibt man Haskell die Anweisung, eine Liste zu bilden aus allen Elementen, die genau durch 3 geteilt werden können: sollen dabei mehrere Bedingungen erfüllt werden, so müssen diese durch Komma getrennt sein. Im Unterschied zu der mathematischen Definition von Mengen können Haskell-Listen sich wiederholende Elemente beinhalten. Prof. Dr. Margarita Esponda Funktionale Programmierung Sieb des Eratosthenes 3. Jahrhundert v. Chr. Das Sieb des Eratosthenes ist ein sehr bekannter Algorithmus, der für ein vorgegebenes N alle Primzahlen findet, die kleiner gleich N sind. Der Algorithmus verwendet ein Feld p aus booleschen Werten, mit dem Ziel, dem Element p[i] den Wert 1 zuzuweisen, falls i eine Primzahl ist, und anderenfalls den Wert 0. Ziel: P P P Prof. Dr. Margarita Esponda P P P 1 2 3 4 5 6 7 8 9 0 1 1 0 1 0 1 0 0 10 11 0 1 Funktionale Programmierung Sieb des Eratosthenes Anfang: 1 1 1 1 1 1 1 1 1 1 2 3 4 5 6 7 8 9 0 1 1 0 1 1 0 1 1 0 1 1 1 0 2 1 3 1 Prof. Dr. Margarita Esponda 4 0 5 1 6 0 7 1 8 0 9 0 1 1 10 0 1 10 0 1 11 1 11 1 1 12 0 1 12 0 1 13 1 13 1 1 14 0 1 14 0 1 15 1 15 0 1 1 16 0 1 16 0 1 17 1 17 1 1 18 0 1 18 0 1 19 1 19 1 1 20 0 1 20 0 1 21 1 21 0 1 Funktionale Programmierung Sieb des Eratosthenes 1 0 1 0 2 3 1 2 1 3 1 1 4 0 4 0 5 1 5 1 6 0 6 0 7 1 7 1 8 0 8 0 9 10 0 0 9 10 0 0 11 1 11 1 12 0 12 0 13 1 13 1 14 15 0 14 0 15 0 0 16 0 16 0 17 1 17 1 18 0 18 0 19 1 19 1 20 0 20 0 0 2 3 1 1 4 0 5 1 6 0 7 1 8 0 nur bis N/2 noch besser ist nur bis Prof. Dr. Margarita Esponda 9 10 0 0 2 N 11 1 12 0 13 1 14 0 0 21 0 N nicht mehr! 1 21 15 0 16 0 17 1 18 0 19 1 20 0 21 0 Funktionale Programmierung Listen-Generatoren primzahlen n = sieb [2..n] where sieb [] = [] sieb (p:x) = p:sieb[k | k<-x, k `mod` p>0] primzahlen2 = sieb [2..] where sieb (p:x) = p:sieb[k | k<-x, k `mod` p>0] Prof. Dr. Margarita Esponda