开发者

remove Repeat values from a list in haskell [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 10 years ago.

I need to accomplish a few tasks in Haskell:

  1. 开发者_C百科

    Find the maximum of a list, along with the number of times it occurs:

    maxCount [2,4,7,2,3] --> [7,1]
    
  2. Remove repeated values from a list

    delRep [1,3,2,1,4] --> [3,2,4]
    
  3. Delete all instances of an element from a list:

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


Question 1.

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

This solution has very bad asymptotic performance because the list is traversed twice. Ideally, a solution would find the maximum and count the repetitions in one pass. If you write maximum, filter, and length in terms of a fold, you should see how to combine them into a single pass.

Also, it would be more natural to return a tuple instead of a list.

Question 2. Look at using Data.Set.Set. Also, does the output list need to be in the same order? If not, there's a particularly easy solution.

Question 3. My above answer for question 1 covers this. That function removes all non-maximum values from the list, which is exactly this problem. Just figure out how that one works, and you'll have this solved as well.


With no builtin functions.. looks really ugly :D

Changed the first a little bit, didn't like that it only works on integers.

-- 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)

Ok, I cheated, I used, filter but you can use remo for that, and elem should be trivial to write.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜