Haskell - 计算列表中每个不同元素出现的次数

时间:2012-05-01 13:55:07

标签: haskell

我是Haskell的新手,我只是想编写一个列表解析来计算列表中每个不同值的频率,但是我在上一部分遇到了麻烦..

到目前为止我有这个:

frequency :: Eq a => [a] -> [(Int,a)] 
frequency list = [(count y list,y) | y <- rmdups ]

涉及rmdups的最后一部分出了问题。

count函数接受一个字符,然后是一个字符列表,并告诉你该字符出现的频率,代码如下。

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

提前谢谢你。

7 个答案:

答案 0 :(得分:14)

在计算频率时,您还可以使用关联数组/有限映射将列表元素中的关联存储到其计数中:

import Data.Map (fromListWith, toList)

frequency :: (Ord a) => [a] -> [(a, Int)]
frequency xs = toList (fromListWith (+) [(x, 1) | x <- xs])

使用示例:

> frequency "hello world"
[(' ',1),('d',1),('e',1),('h',1),('l',3),('o',2),('r',1),('w',1)]

请参阅fromListWithtoList的文档。

答案 1 :(得分:11)

由于使用了Ord

,我必须使用Eq代替sort而不是frequency :: Ord a => [a] -> [(Int,a)] frequency list = map (\l -> (length l, head l)) (group (sort list))
{{1}}

答案 2 :(得分:6)

根据要求,这是使用Control.Arrow的解决方案:

frequency :: Ord a => [a] -> [(Int,a)] 
frequency = map (length &&& head) . group . sort

这与 ThePestest 的答案功能相同,但

除外
λ f g l -> (f l, g l)

替换为

-- simplified type signature
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)

来自Control.Arrow。如果你想避免导入,

liftA2 (,) :: Applicative f => f a -> f b -> f (a, b)

同样适用(使用(->) r)的适用实例

答案 3 :(得分:4)

假设rmdups的类型为

rmdups :: Eq a => [a] -> [a]

然后你错过了一个参数。

frequency :: Eq a => [a] -> [(Int,a)] 
frequency list = [(count y list,y) | y <- rmdups list]

但是你得到的错误对诊断有帮助。

答案 4 :(得分:0)

rmdups nub功能只是来自Data.List的{​​{1}}。

答案 5 :(得分:0)

rmdups取代nub list就像魅力一样为我工作。

答案 6 :(得分:0)

哈哈哈哈,pg上有一个rmdups。 Graham Hutton撰写的 Haskell编程中的86篇。它是完美的和递归的。它在很多情况下也很方便。

这是我的一行rmdups,它产生与nub或Hutton相同的结果。

rmdups ls = [d|(z,d)<- zip [0..] ls,notElem d $ take z ls]

它可以用于计算列表中不同的元素。

dl = "minimum-maximum"
[ (d,sum [1|x<-dl,d == x]) | d<-rmdups dl]

[( 'M',6),( 'I',3),( 'N',1),( 'U',2),( ' - ',1),( '一个',1 ),( 'X',1)]