TU Wien:Funktionale Programmierung VU (Knoop)/Prüfung 2015-01-15
Aufgabe 1[Bearbeiten | Quelltext bearbeiten]
Geben Sie die Werte bzw. den allgemeinsten Typ von t1 bis t7 an. (Hier im VoWi kannst du die leeren Zeilen auswählen um die Lösungen zu sehen.)
Aufgabe 2[Bearbeiten | Quelltext bearbeiten]
Erstellen sie einen polymorphen algebraischen Datentyp BTree der einem Binärbaum entspricht. Jeder Knoten enthält ein polymorphes Element und zwei Unterbäume. Ein Knoten bzw. die Unterbäume können auch leer sein.
data BTree a = Nil | Node a (BTree a) (BTree a)
Aufgabe 3[Bearbeiten | Quelltext bearbeiten]
Geben Sie einen konkreten Wert für folgenden Typ in Haskell-Syntax inklusive Zeichnung an: ( BTree Integer, BTree String ). Die Bäume sollen die Werte 1,2 und "ab" enthalten.
(Node 1 (Node 2 Nil Nil) Nil, Node "ab" Nil Nil)
Aufgabe 4[Bearbeiten | Quelltext bearbeiten]
Definieren Sie eine Funktion jdif die für einen BTree genau dann True liefert, wenn für jeden Knoten gilt, dass das Element des Knotens nicht in den Unterbäumen des Knotens vorkommt. (Typklasse!)
jdif :: Eq a => (BTree a) -> Bool
jdif Nil = True
jdif (Node a Nil Nil) = True
jdif (Node a n@(Node b Nil Nil) Nil)
| a /= b = and [True, jdif n]
| otherwise = False
jdif (Node a Nil n@(Node b Nil Nil))
| a /= b = and [True, jdif n]
| otherwise = False
jdif (Node a n1@(Node b Nil Nil) n2@(Node c Nil Nil))
| and [a /= b, a /= c] = and [True, jdif n1, jdif n2]
| otherwise = False
Bei dieser Aufgabe habe ich extra den Professor gefragt, ob das Element nur nicht in den direkten Unterbäumen gleich sein darf, oder in den gesamten Unterbäumen (und deren Unterbäume, ...). Worauf er gemeint hat, dass es für die gesamten Unterbäume etwas zu aufwändig wäre. Deswegen habe ich die Funktion so geschrieben, dass sie nur für die direkten Unterbäume (bzw. Knoten) gilt. (Hoffentlich wird das auch so gewertet beim Verbessern.)
Alternative Lösung[Bearbeiten | Quelltext bearbeiten]
Interpretiert man die Angabe so, dass das Element auch in den indirekten Unterbäumen nicht vorkommen darf, könnte man dafür folgende Lösung verwenden:
jdif :: Eq a => BTree a -> Bool
jdif t = jdif' t []
where
jdif' (Node a t1 t2) l
| elem a l = False
| otherwise = jdif' t1 (a:l) && jdif' t2 (a:l)
jdif' Nil _ = True
Die Lösung ist allerdings speicherintensiv, da die gefundenen Elemente in Listen verwaltet werden, dafür wird allerdings jeder Knoten nur einmal angesehen.
Alternativ könnte man auch eine wenig speicher- dafür laufzeitintensive Funktion verwenden:
jdif2 :: Eq a => BTree a -> Bool
jdif2 (Node a t1 t2) = jdif' t1 a && jdif' t2 a && jdif2 t1 && jdif2 t2
where
jdif' (Node a t1 t2) b
| a == b = False
| otherwise = jdif' t1 b && jdif' t2 b
jdif' Nil _ = True
jdif2 Nil = True
Aufgabe 5[Bearbeiten | Quelltext bearbeiten]
Definieren Sie filtert, das eine einstellige boolsche Funktion und einen BTree erwartet und eine Liste jener Elemente in beliebiger Reihenfolge zurückliefert, bei denen die Funktion für das Element True ist. Geben Sie auch hier eine möglichst allgemeine Typdeklaration für filtert an!
filtert :: (a -> Bool) -> BTree a -> [a]
filtert _ Nil = []
filtert f (Node a l r) = [a | f a] ++ filtert f l ++ filtert f r