如何通过列表理解来计算频率?

时间:2012-04-27 18:28:56

标签: list haskell

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



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

使用2个函数,需要创建第三个函数,称为频率: 它应该计算列表中每个不同值出现在该列表中的次数。例如:频率“ababc”,应返回[(3,'a'),(2,'b'),(1,'c')]。 频率的布局是:

frequency :: Eq a => [a] -> [(Int, a)]

P.s rmdups,从列表中删除重复项,因此rmdups“aaabc”= abc 并计数2 [1,2,2,2,3] = 3.

到目前为止,我有:

frequency :: Eq a => [a] -> [(Int, a)]
frequency [] = []
frequency (x:xs) = (count x:xs, x) : frequency (rmdups xs)

但这部分存在,(错误)。感谢

3 个答案:

答案 0 :(得分:1)

frequency xs = map (\c -> (count c xs,c)) (rmdups xs)

或者,通过列表理解,

frequency xs = [(count c xs, c) | c <- rmdups xs]

是使用countrmdups定义它的最短方式。如果你需要它按照频率(降序)排序,如你的例子,

frequency xs = sortBy (flip $ comparing fst) $ map (\c -> (count c xs,c)) (rmdups xs)

使用sortBy中的Data.Listcomparing中的Data.Ord

如果您只拥有Eq约束,则无法获得更高的效率,但如果您只需要Ord中的类型,则可以使用例如{...}}获得更高效的实施方式。 Data.SetData.Map

答案 1 :(得分:1)

这是我自己的'懒惰'答案,它不会调用rmdups:

frequency [] = []
frequency (y:ys) = [(count y (y:ys), y)] ++ frequency (filter (/= y) ys)

答案 2 :(得分:0)

import qualified Data.Set as Set

frequency xs = map (\x -> (length $ filter (== x) xs, x)) (Set.toList $ Set.fromList xs)