17

我是 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

先感谢您。

4

7 回答 7

23

您还可以在计算频率时使用关联数组/有限映射来存储从列表元素到它们的计数的关联:

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

fromListWith请参阅和的文档toList

于 2014-03-14T07:17:52.727 回答
15

我不得不使用Ordin 而不是Eq因为使用sort

frequency :: Ord a => [a] -> [(Int,a)] 
frequency list = map (\l -> (length l, head l)) (group (sort list))
于 2012-05-01T14:08:22.860 回答
7

根据要求,这是使用的解决方案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)

也可以(使用 Applicative 实例(->) r

于 2014-10-14T23:46:45.043 回答
5

Assuming rmdups has the type

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

Then you're missing a parameter for it.

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

But the error you're getting would be helpful with diagnosis.

于 2012-05-01T14:12:10.143 回答
1

您的rmdups功能只是nub来自Data.List.

于 2012-05-01T14:02:17.327 回答
0

替换rmdupsnub list我工作就像一个魅力。

于 2014-03-14T06:55:11.597 回答
0

哈哈哈哈哈哈rmdupspg上有。Graham Hutton在 Haskell中编程的第 86篇。它是完美的和递归的。它在很多情况下也很方便。

这是我的一条线rmdups,它产生的结果与nub赫顿的相同。

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),('a',1),( 'x',1)]

于 2018-05-06T13:23:59.980 回答