[haskell]写了一个哈夫曼编解码的程序
初学者,纯练手。haskell的类型系统过于强大,以致写程序时大量时间是跟类型不匹配打交道,不过带来的好处就是一旦编译通过,多半就能work了
1 data Tree a = Empty | Branch a (Tree a) (Tree a)
2 deriving (Show, Eq)
3 isLeaf (Branch a Empty Empty) = True
4 isLeaf _ = False
5 value::(Num t, Ord t, Show t) => Tree t -> t
6 value Empty = 0
7 value (Branch a _ _ ) = a
8 getMinOne::(Num a, Ord a) => [Tree a] -> (Tree a, [Tree a])
9 getMinOne [] = (Empty, [])
10 getMinOne (x:[]) = (x, [])
11 getMinOne (x:xs) = let (m, xxs) = (getMinOne xs) in
12 if (value x) < (value m) then ( x, [m]++xxs ) else
13 (m, [x]++xxs)
14 getMinTwo [] = (Empty, Empty, [])
15 getMinTwo xs = let (one, last) = (getMinOne xs) in
16 let (two, llast ) = (getMinOne last) in
17 (one, two, llast)
18 haff :: (Ord a, Num a) => [a] -> [Tree a]
19 haff [] = []
20 haff xs = haffs ( map (\x -> Branch x Empty Empty) xs ) where
21 haffs xxs = if ((length xxs) == 1) then xxs else
22 let ( one, two, last ) = (getMinTwo xxs) in
23 haffs ([(Branch ( (value one) + (value two) ) one two )] ++ last )
24
25 encodOne ch (Branch v l f) result = if ( v == ch && (isLeaf (Branch v l f)) ) then result else
26 if ( v /= ch && (isLeaf (Branch v l f))) then "" else
27 if( lv == "" && rv /= "" ) then rv else lv where
28 lv = (encodOne ch l ("0"++result))
29 rv = (encodOne ch f ("1"++result))
30 haffEncod [] = []
31 haffEncod xs = let [t] = (haff xs) in
32 map ( \x -> encodOne x t "" ) xs
33
34 decodOne:: (Ord a, Num a) => [Char] -> (Tree a) -> a
35 decodOne (x:[]) (Branch v l r) = if [x] == "0" then (value l) else (value r)
36 decodOne (x:xs) (Branch v l r) = if [x] == "0" then decodOne xs l else decodOne xs r
37
38 haffDecod :: (Ord a, Num a) => [[Char]] -> [a] -> [a]
39 haffDecod [] _ = []
40 haffDecod xs [] = []
41 haffDecod xs dic = let [t] = (haff dic) in
42 map ( \x -> decodOne x t ) xs
2 deriving (Show, Eq)
3 isLeaf (Branch a Empty Empty) = True
4 isLeaf _ = False
5 value::(Num t, Ord t, Show t) => Tree t -> t
6 value Empty = 0
7 value (Branch a _ _ ) = a
8 getMinOne::(Num a, Ord a) => [Tree a] -> (Tree a, [Tree a])
9 getMinOne [] = (Empty, [])
10 getMinOne (x:[]) = (x, [])
11 getMinOne (x:xs) = let (m, xxs) = (getMinOne xs) in
12 if (value x) < (value m) then ( x, [m]++xxs ) else
13 (m, [x]++xxs)
14 getMinTwo [] = (Empty, Empty, [])
15 getMinTwo xs = let (one, last) = (getMinOne xs) in
16 let (two, llast ) = (getMinOne last) in
17 (one, two, llast)
18 haff :: (Ord a, Num a) => [a] -> [Tree a]
19 haff [] = []
20 haff xs = haffs ( map (\x -> Branch x Empty Empty) xs ) where
21 haffs xxs = if ((length xxs) == 1) then xxs else
22 let ( one, two, last ) = (getMinTwo xxs) in
23 haffs ([(Branch ( (value one) + (value two) ) one two )] ++ last )
24
25 encodOne ch (Branch v l f) result = if ( v == ch && (isLeaf (Branch v l f)) ) then result else
26 if ( v /= ch && (isLeaf (Branch v l f))) then "" else
27 if( lv == "" && rv /= "" ) then rv else lv where
28 lv = (encodOne ch l ("0"++result))
29 rv = (encodOne ch f ("1"++result))
30 haffEncod [] = []
31 haffEncod xs = let [t] = (haff xs) in
32 map ( \x -> encodOne x t "" ) xs
33
34 decodOne:: (Ord a, Num a) => [Char] -> (Tree a) -> a
35 decodOne (x:[]) (Branch v l r) = if [x] == "0" then (value l) else (value r)
36 decodOne (x:xs) (Branch v l r) = if [x] == "0" then decodOne xs l else decodOne xs r
37
38 haffDecod :: (Ord a, Num a) => [[Char]] -> [a] -> [a]
39 haffDecod [] _ = []
40 haffDecod xs [] = []
41 haffDecod xs dic = let [t] = (haff dic) in
42 map ( \x -> decodOne x t ) xs
最近在做Ninety-Nine Haskell Problems已经做到第80题了