【问题标题】:code / decode Huffman Tree Haskell编码/解码哈夫曼树 Haskell
【发布时间】:2018-08-15 19:42:06
【问题描述】:

我之前问了一个关于如何制作树的问题,但现在我又被卡住了。 我想对我的霍夫曼树进行编码和解码

所以这些是我的类型:

module Types where


type Occurence  = (Number, Value)
type Occurences = [Occurence]
type Number     = Int
type Value      = Char
type Code       = [Directions]
type CodeTable  = [(Value, Code)]


data Directions = L | R deriving (Eq, Ord, Show)


data HTree      = Leaf {frequency :: Number, character:: Value} |
                  Node {frequency:: Number, 
                        leftChild:: HTree,
                        rightChild:: HTree} deriving Show

makeLeaf :: Occurence -> HTree
makeLeaf (n, c) = Leaf n c

这些是我已经编写的函数,它们实际上正在工作:

makeTree :: Occurences -> HTree
makeTree = makeCodes . toTreeList

toTreeList :: Occurences -> [HTree]
toTreeList = map (uncurry Leaf)

h :: [HTree] -> [HTree]
h (t1:t2:ts) = insertTree (join t1 t2) ts

makeCodes :: [HTree] -> HTree
makeCodes [t] = t
makeCodes ts = makeCodes (h ts)

join :: HTree -> HTree -> HTree
join t1 t2 = Node (freq1+freq2) t1 t2
    where
      freq1 = v t1
      freq2 = v t2

v :: HTree -> Int
v (Leaf n _ ) = n
v (Node n _ _) = n

insertTree :: HTree -> [HTree] -> [HTree]
insertTree t [] = [t]
insertTree t (t1:ts) 
     | v t < v t1 = t:t1:ts
     | otherwise = t1 : insertTree t ts




constructTable :: HTree -> CodeTable
constructTable = convert []
      where
      convert :: Code -> HTree -> CodeTable
      convert hc (Leaf n c) = [(c, hc)]
      convert hc (Node n tl tr) = (convert (hc++[L]) tl) ++ (convert (hc++[R]) tr)

现在我想编写一个解码器...

code :: String -> (Code, CodeTable)

decode :: Code -> CodeTable -> String
decode code table = undefined

我通常会这样处理

code :: HTree -> Char -> String
code (Leaf c n) x
| c==x = []
| otherwise = error "!!"
code (Node li n re) x
| member x li = ’L’:code li x
| otherwise = ’R’:code re x
where member a (Leaf c n) = (a==c)
member a (Node li c re) = (member a li) || (member a re)

但是如何使用 CodeTable 做到这一点?

【问题讨论】:

    标签: haskell huffman-code


    【解决方案1】:

    好吧,当您知道出现次数时,您就知道如何制作树了,所以我想您应该弄清楚如何从字符串中出现次数。

    import Data.Map as M
    frequencyTable :: String -> Occurrences
    frequencyTable = sort . map (uncurry flip) . M.toList . M.fromListWith (+) . map (\x -> (x,1))
    

    所以现在您可以为字符串制作霍夫曼代码:

    codeTable : String -> CodeTable
    codeTable = constructTable . makeTree . frequencyTable
    

    当你有霍夫曼代码时,你知道如何对字符串进行编码:

    code1 [] char = error “not in code table”
    code1 ((c1,code)::table) char
      | c1 == char = code
      | otherwise = code1 table char
    code s = (s >>= code1 table, table) where
      table = codeTable s
    

    解码有点繁琐,您可能希望将代码表转换为树,以便您可以直接做出决定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多