从haskell中的列表中删除重复值

时间:2011-07-08 21:54:40

标签: haskell

我需要在Haskell中完成一些任务:

  1. 查找列表的最大值及其出现次数:

    maxCount [2,4,7,2,3] --> [7,1]
    
  2. 从列表中删除重复的值

    delRep [1,3,2,1,4] --> [3,2,4]
    
  3. 从列表中删除元素的所有实例:

    delete [1,3,4,1] 1 --> [3,4]
    

2 个答案:

答案 0 :(得分:2)

问题1。

maxAndReps l = let m = maximum l
                   reps = length $ filter (== m) l
               in [m,reps]

此解决方案具有非常糟糕的渐近性能,因为列表遍历了两次。理想情况下,解决方案会在一次通过中找到最大值并计算重复次数。如果您在折叠方面写下maximumfilterlength,您应该会看到如何将它们合并为一次。

此外,返回元组而不是列表会更自然。

问题2.请使用Data.Set.Set。此外,输出列表是否需要按相同的顺序排列?如果没有,那就是一个特别简单的解决方案。

问题3.我对问题1的上述答案涵盖了这一点。该函数从列表中删除所有非最大值,这正是这个问题。只要弄清楚它是如何工作的,你也可以解决这个问题。

答案 1 :(得分:-2)

没有内置功能..看起来很丑:D

稍微更改了第一个,不喜欢它只适用于整数。

-- 1.
maxic :: Ord a => [a] -> (a, Integer)
maxic xs = (x,c)
  where x = maxi xs
         where maxi :: Ord a => [a] -> a
               maxi [] = error "empty list"
               maxi (x:xs) = iter xs x
                 where iter [] m = m
                       iter (x:xs) m | x > m = iter xs x
                       iter (_:xs) m = iter xs m
        c = cnt xs x
          where cnt :: Eq a => [a] -> a -> Integer
                cnt (x:xs) e | x==e = 1 + (cnt xs e)
                cnt (_:xs) e = cnt xs e
                cnt _ _ = 0

-- 2.
remrep :: Eq a => [a] -> [a]
remrep xs = reverse (iter xs [])
  where iter (x:xs) res | elem x res = iter xs (filter (/= x) res)
        iter (x:xs) res = iter xs (x:res)
        iter [] res = res

-- 3.
remo :: Eq a => [a] -> a -> [a]
remo [] e = []
remo (x:xs) e | x==e = remo xs e
remo (x:xs) e = (x : remo xs e)

好吧,我作弊,我曾经使用过滤器,但你可以使用remoelem应该可以轻松写入。