Haskell运行长度编码功能

时间:2017-05-04 02:32:24

标签: list haskell encoding integer tuples

此编码功能需要以下输出, code "aaccbbaa" = [('a',2),('c',2),('b',2),('a',2)

然而,这是我的输出。 code "aaccbbaa" = [('a',4),('c',2),('b',2)]

这是我的功能,

code :: Eq a => [a] -> [(a,Int)]
code [] = []
code (x:xs) = [(x, length(filter(==x)(x:xs)))] ++ code(filter (/=x)(xs))

如何在下一个alpha字母出现时重新计算?

2 个答案:

答案 0 :(得分:1)

Data.List

中有group个功能
code :: Eq a => [a] -> [(a,Int)]
code = map (\x -> (head x, length x)) . group
λ> code "aaccbbaa"
[('a',2),('c',2),('b',2),('a',2)]

答案 1 :(得分:0)

具有帮助函数的foldr应足以处理此作业,如下所示;

code :: Char -> [(Char,Int)] -> [(Char,Int)]
code c [(_,0)]    = [(c,1)]
code c ((x,n):ts) | c == x    = (x,n+1):ts
                  | otherwise = (c,1):(x,n):ts

rle :: String -> [(Char,Int)]
rle = foldr code [(' ',0)]

根据您的评论接受Eq类实例的任何类型,我们可以简化rle函数。另一方面,接受的答案涉及3次执行操作,例如groupmaplength。对于一次性使用它无关紧要,但是如果你将在某些单词或句子上使用这个函数数百万次,那么我会建议以下只能在列表中运行一次。

rle :: Eq a => [a] -> [(a,Int)]
rle = foldr code []
      where code c []         = [(c,1)]
            code c ((x,n):ts) | c == x    = (x,n+1):ts
                              | otherwise = (c,1):(x,n):ts