http://pl.wikipedia.org/wiki/LZ78 这是一个波兰维基百科网站,但它包含一个python代码,可用于检查haskell代码是否有效
我使用示例中的文字: abbbcaabbcbbcaaac
我的问题是,当trace以正确的顺序显示char / int对时,它们会以某种方式在输出列表中混乱。有人可以解释一下发生了什么吗?
这是正确的顺序: (0,A) (0,b)中 (2,B) (0,c)中 (1,A) (3,c)中 (参照图6,) (5,c)中
import System.IO
import Control.Monad
import qualified Data.Map as Map
import Debug.Trace
main = do
contents <- readFile "file.txt"
print $ compress contents Map.empty 1 "" []
compress :: String -> Map.Map String Int -> Int -> String -> [(Int,Char)]-> [(Int,Char)]
compress (s:x) m i c out = do
if Map.member (c++[s]) m == False
then do
if c == ""
then do
let newMap = trace( show s ++ " 0 aaaaaa\n") Map.insert [s] i m
compress x newMap (i+1) c (out++[(0,s)])
else do
let newMap = trace(show s ++ " " ++ show (m Map.! c) ++ " bbbbb\n") Map.insert (c++[s]) i m
compress x newMap (i+1) "" out++[(newMap Map.! c, s)]
else compress x m i (c++[s]) out
compress s m i c out = compress2 out
compress2 :: [(Int,Char)]-> [(Int,Char)]
compress2 out = out
答案 0 :(得分:2)
这是一个括号错误:
compress x newMap (i+1) "" out++[(newMap Map.! c, s)]
解析为
(compress x newMap (i+1) "" out) ++ [(newMap Map.! c, s)]
但你想要
compress x newMap (i+1) "" (out++[(newMap Map.! c, s)])
顺便说一句,有趣的问题。我尝试重写你的代码,使其更加惯用:
import System.IO
import Data.Map as M
import Prelude as P
main = do
contents <- readFile "file.txt"
print $ compress contents
compress :: String -> [(Int, Char)]
compress = reverse . third . P.foldl step (singleton "" 0, "", [])
where step (dict, pat, log) char =
let pat' = char:pat
in if member pat' dict
-- `pat'` is already in our dictionary, so
-- we've previously extended `pat` by `char`, and
-- we don't need to record anything
then (dict, pat', log)
-- pat' is new to us, so
-- * assign it a new id in the dictionary
-- * start reading a new pattern
-- * record it in the log
else (insert pat' (size dict) dict, "", (dict ! pat, char):log)
third (_, _, log) = log