Huffman符号木
情報理論の宿題のうちの1問,「これこれの確率分布に対してHuffman符号木を書け」をHaskellで解いてみた.情報理論は計数の科目なので.
nodakai@co:/mnt/windows/home/nodakai/prog/haskell$ hugs huffman.hs (略) Main> main Input (probabilities for each alphabet): [('a',0.25),('b',0.25),('c',0.2),('d',0.15),('e',0.1),('f',0.05)] Output (Huffman code tree and table): +:1.0 +:0.45 --'c':0.2 --'b':0.25 +:0.55 --'a':0.25 +:0.3 --'d':0.15 +:0.15 --'f':0.05 --'e':0.1 [('c',"00"),('b',"01"),('a',"10"),('d',"110"),('f',"1110"),('e',"1111")]
module Main where import IO import List data BinTree a p = Leaf a p | Branch (BinTree a p) (BinTree a p) p binTreeShow (Leaf x p) d h = (if h then wsGen d else "") ++ "--" ++ (show x) ++ ":" ++ (show p) binTreeShow (Branch l r p) d h = (if h then wsGen d else "") ++ "+:" ++ pStr ++ " " ++ (binTreeShow l dnew False) ++ "\n" ++ (binTreeShow r dnew True) where pStr = show p dnew = d+(length pStr)+3 wsGen n = loop n "" where loop 0 acc = acc loop n acc = loop (n-1) (' ':acc) instance (Show a, Show p) => Show (BinTree a p) where show x = binTreeShow x 0 False occuranceProbabilities = [('a', 0.25), ('b', 0.25), ('c', 0.2), ('d', 0.15), ('e', 0.1), ('f', 0.05)] main = do putStrLn "Input (probabilities for each alphabet): " putStrLn $ show occuranceProbabilities putStrLn "" putStrLn "Output (Huffman code tree and table):" putStrLn $ show $ huffmanTree putStrLn $ show $ tablize $ huffmanTree where huffmanTree = huffmanTreefy occuranceProbabilities huffmanTreefy spec = loop (sortBy od init) where init = map (\ (ch, p) -> (p, (Leaf ch p))) spec od (p1, _) (p2, _) = if p1 < p2 then LT else GT loop [] = Leaf 'Q' 0 loop [(p, tr)] = tr loop ((px, trX):(py, trY):rest) = loop sorted where sorted = sortBy od ((pp, (Branch trX trY pp)):rest) where pp = px+py tablize tree = map (\ (c,s) -> (c, reverse s)) (rec tree "") where rec (Leaf x p) acc = [(x, acc)] rec (Branch l r p) acc = (rec l ('0':acc)) ++ (rec r ('1':acc))
ちなみに宿題の提出期限はとっくに過ぎている.