2
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 つの関数を使用して、頻度と呼ばれる 3 番目の関数を作成する必要があります。これは、リスト内の各個別の値がそのリストで何回出現するかをカウントする必要があります。例: 頻度 "ababc" は、[(3,'a'),(2,'b'),(1,'c')] を返す必要があります。頻度のレイアウトは次のとおりです。

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

Ps rmdups、リストから重複を削除するため、rmdups "aaabc" = abc および count 2 [1,2,2,2,3] = 3.

これまでのところ、私は持っています:

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

しかし、これは部分的に存在します (間違っています)。ありがとう

4

3 に答える 3

1

これは、rmdupsを呼び出さない私自身の「怠惰な」答えです。

frequency [] = []
frequency (y:ys) = [(count y (y:ys), y)] ++ frequency (filter (/= y) ys)
于 2013-01-31T05:26:18.603 に答える
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)

sortByfromData.Listcomparingfromを使用しData.Ordます。

制約しかない場合Eq、あまり効率を高めることはできませんが、 の型にのみ必要な場合は、 egまたはOrdを使用してはるかに効率的な実装を得ることができます。Data.SetData.Map

于 2012-04-27T18:44:48.070 に答える
0

import qualified Data.Set as Set

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

于 2012-04-27T18:57:34.943 に答える