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)
但这部分存在,(错误)。感谢
答案 0 :(得分:1)
frequency xs = map (\c -> (count c xs,c)) (rmdups xs)
或者,通过列表理解,
frequency xs = [(count c xs, c) | c <- rmdups xs]
是使用count
和rmdups
定义它的最短方式。如果你需要它按照频率(降序)排序,如你的例子,
frequency xs = sortBy (flip $ comparing fst) $ map (\c -> (count c xs,c)) (rmdups xs)
使用sortBy
中的Data.List
和comparing
中的Data.Ord
。
如果您只拥有Eq
约束,则无法获得更高的效率,但如果您只需要Ord
中的类型,则可以使用例如{...}}获得更高效的实施方式。 Data.Set
或Data.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)