为什么不给出正确的输出?

时间:2012-04-23 19:10:17

标签: haskell

count :: Eq a => a -> [a] -> Int
count _[]                  = 0
count z (x:xs) | z == x    = 1 + (count z xs)
               | otherwise = count z xs

rmdups :: Eq a => [a] -> [a]
rmdups [] = []
rmdups (x:xs) | count x xs > 0 = rmdups xs
              | otherwise     = x: rmdups xs

上面的代码编译但是当我输入'ababca'时,rmdups的输出是'bca',我希望它是'abc'。为什么去那里?我一直在改变代码,并且不知道为什么会这样做。

2 个答案:

答案 0 :(得分:10)

因为您从前面删除了重复项。在继续之前,您可以修改rmdups以过滤掉xs,因此重复项会从尾部中删除:

rmdups :: Eq a => [a] -> [a]
rmdups [] = []
rmdups (x:xs)
    | count x xs > 0 = x : (rmdups $ filter (/= x) xs)
    | otherwise      = x : rmdups xs

事实上,你甚至可以在没有预先安排的情况下这样做:

rmdups :: Eq a => [a] -> [a]
rmdups []       = []
rmdups (x : xs) = x : filtered
                where filtered = rmdups $ filter (/= x) xs

当然,在实际代码中,您应该更喜欢已经可用的函数,在本例中为Data.List.nub

答案 1 :(得分:1)

您的rmdups函数会移除除每个字符的 last 之外的所有内容。

如果您要删除除每个字符的第一个以外的所有内容,您可以尝试

reverse . rmdups . reverse

(即,在使用rmdups之前和之后反转),或者您可以重写rmdups以跟踪之前发生过的所有字符。