Huffman Encoding

From HaskellWiki
Revision as of 14:06, 23 May 2009 by Kashyap (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

data WeightCharacterTuple = WeightCharacterTuple { weight :: Int, character :: Char }deriving (Show) instance Eq WeightCharacterTuple where a == b = (weight a) == (weight b) instance Ord WeightCharacterTuple where a > b = (weight a) > (weight b) a >= b = (weight a) >= (weight b) a < b = (weight a) < (weight b) a <= b = (weight a) <= (weight b) data Tree a = Node a (Tree a) (Tree a) | Leaf a deriving (Show) instance Eq a => Eq (Tree a) where (==) a b = (node a) == (node b) node x = case x of (Node n _ _) -> n (Leaf n) -> n instance Ord a => Ord (Tree a) where left >= right = (node left) >= (node right) left < right = (node left) < (node right) left > right = (node left) > (node right) left <= right = (node left) <= (node right) toFrequencyCharacterTuple :: String -> [WeightCharacterTuple] toFrequencyCharacterTuple string = quickSort $ zipWith WeightCharacterTuple counts uniqueLetters where counts = map (frequency string) uniqueLetters frequency :: String -> Char -> Int frequency (x:xs) c | c == x = 1 + frequency xs c | otherwise = frequency xs c frequency _ c = 0 uniqueLetters = unique string unique :: String -> String -- get the unique letters in the string unique (x:xs) = [x] ++ unique [y | y <- xs, y /= x ] unique [] = [] huffman :: [Tree WeightCharacterTuple] -> [Tree WeightCharacterTuple] huffman (min1:min2:rest) = huffman newList where newList | length rest /= 0 = quickSort ((merge min1 min2):rest) | otherwise = [merge min1 min2] where merge a b | a <= b = Node (WeightCharacterTuple newWeight '*') a b | otherwise = Node (WeightCharacterTuple newWeight '*') b a where newWeight = (weight (node a)) + (weight (node b)) huffman x = x x `endsWith` y = (take (length y) (reverse x)) == (reverse y) encode::WeightCharacterTuple -> Tree WeightCharacterTuple -> String encode w (Node n left right) = oneOf ('0':(encode w left)) ('1':(encode w right)) where oneOf x y | y `endsWith` "WRONG-LEAF" = x | otherwise = y encode w (Leaf l) | (character l) == (character w) = "" | otherwise = "WRONG-LEAF" quickSort (x:xs) = l1 ++ [x] ++ l2 -- items less than x + x + items bigger than x where l1 = quickSort [y | y <- xs, y < x] -- sorted items less than x l2 = quickSort [y | y <- xs, y >= x] -- sorted items greater than x quickSort [] = [] displayAllEncodings :: [WeightCharacterTuple] -> Tree WeightCharacterTuple -> String displayAllEncodings (x:xs) tree= (codeForX x) ++ "\n" ++ (displayAllEncodings xs tree) where codeForX (WeightCharacterTuple w c) = (show c) ++ " weight = " ++ (show w) ++ " code = " ++ (encode x tree) displayAllEncodings _ _ = [] main=do x <- getLine let tupleList=toFrequencyCharacterTuple x let inputTreeList=map Leaf tupleList let tree=huffman inputTreeList putStrLn (show tree) putStrLn (displayAllEncodings tupleList (tree!!0)) return ()