Haskell - 霍夫曼解码没有树

时间:2015-01-04 11:42:07

标签: haskell decoding huffman-code

因此,对于我已经给出的赋值,我有三个函数需要完成,即从给定树的每个叶节点中提取HCodeMap,将字符串编码为Bits列表,并解码该字符串比特回到一个字符串。

我已经成功完成了代码提取和编码功能,但是我很难在最后一个解码函数上取得进展,因为我们不允许遍历树,因为我们没有使用它。

这是函数的格式,后跟我们提供的一些类型:

decode :: [Bit] -> HCodeMap -> Maybe String 

data Bit = Zero | One deriving (Show, Eq)
type HCodeMap = [(Char, [Bit])]

我最初尝试创建自己的查找函数,它将交换HCodeMap的值,然后从我们给出的Bits列表中查找前n位。

我将用一个例子来说明我是否还没有说清楚:

[比特]我们得到:[One,Zero,One,One,Zero]

我们给出了HCodeMap:[(' c',[Zero]),(' a',[One,Zero]),(' b& #39;,[一,一)]

我计划从列表中获取第一个位,即One,然后搜索HCodeMap测试以查看它是否等于那里的任何[Bit]。

这是我的反向查找功能会进入的地方,因为我可以查找HCodeMap中的位列表,因为我无法通过字母查找。这是:

查找(我们在这里给出的位)(每个HCodeMap元组)$ map swap code

在这种情况下,我们看到One与任何HCodeMap元组都不匹配,因此我测试One,Zero。这符合' a'所以我添加' a'到一个字符串,然后继续下一个[Bit]我们通过,再次成为一个。

等继续这样,我们留下了字符串" abc"。

我真的在努力将这个实际放入一个函数中。

我希望我没有让这个太混乱,谢谢你事先提供任何帮助!

1 个答案:

答案 0 :(得分:3)

尝试连续解析所有代码,然后在成功匹配后重复。重复,直到没有更多输入。

import Control.Monad

data Bit = Zero | One deriving (Show, Eq)
type HCodeMap = [(Char, [Bit])]

decode :: [Bit] -> HCodeMap -> Maybe String
decode bits codes = process bits where

  -- if the code matches the input, return the corresponding 
  -- Char value along with the rest of of the input
  match :: (Char, [Bit]) -> [Bit] -> Maybe (Char, [Bit])
  match (v, xs) ys = go xs ys where
    go (x:xs) (y:ys) | x == y = go xs ys
    go []     ys              = Just (v, ys)
    go _      _               = Nothing

  -- match and consume until there's no more input, or fail if there is no match.
  -- note that msum takes the first Just from a list of Maybe-s, 
  -- or returns Nothing if there isn't any
  process :: [Bit] -> Maybe String
  process [] = Just []
  process xs = do
    (v, xs) <- msum $ map (`match` xs) codes
    (v:) `fmap` process xs

对于那些不熟悉msum的人,这里的实现专门针对Maybe

msum :: [Maybe a] -> Maybe a
msum (Just a:xs)  = Just a
msum (Nothing:xs) = msum xs
msum []           = Nothing