如何計算字符串中字符的頻率然後以表格的形式輸出它們?如何在Haskell中查找字符串中的字符頻率?
例如,如果我輸入單詞「幸福」的結果將是
h 1
a 1
p 2
y 1
如果能在ASCII順序進行排序也將是輝煌的。
我知道我需要使用計數功能,任何其他提示將不勝感激。
編輯:所有的答案都輝煌,只是我在哈斯克爾這樣的初學者,我不真正瞭解自己在做什麼。
如何計算字符串中字符的頻率然後以表格的形式輸出它們?如何在Haskell中查找字符串中的字符頻率?
例如,如果我輸入單詞「幸福」的結果將是
h 1
a 1
p 2
y 1
如果能在ASCII順序進行排序也將是輝煌的。
我知道我需要使用計數功能,任何其他提示將不勝感激。
編輯:所有的答案都輝煌,只是我在哈斯克爾這樣的初學者,我不真正瞭解自己在做什麼。
有可能是一些短,但這個工程:
Prelude> import Data.List
Prelude Data.List> map (\x -> (head x, length x)) $ group $ sort "happy"
[('h',1),('a',1),('p',2),('y',1)]
最簡單的解決方法是使用一個Data.Map
到中間映射存儲從字符頻率。然後您可以使用fromListWith
輕鬆構建計數。由於Data.Map
已排序,因此您可以免費獲得ASCII碼。
λ> :m + Data.Map
λ> let input = "happy"
λ> toList $ fromListWith (+) [(c, 1) | c <- input]
[('a',1),('h',1),('p',2),('y',1)]
所以這裏發生了什麼?
的想法是使用字符鍵和頻率,值,以建立一個Data.Map
(樹地圖)。
首先,我們將輸入字符串與每個字符的元組作一個1
來表示一個事件。
λ> [(c, 1) | c <- input]
[('h',1),('a',1),('p',1),('p',1),('y',1)]
接下來,我們使用fromListWith
通過重複地將每個鍵 - 值對成映射建立從這些鍵 - 值對的有序映射。我們還給它一個函數,當一個鍵已經在地圖上時,它將被使用。在我們的例子中,我們使用(+)
,這樣當一個角色被多次查看時,我們會將計數添加到現有總和中。
最後,我們使用toList
將地圖轉換回鍵值元組列表。
我會scetch的解決方案分步實施。使用標準功能可以縮短解決方案的時間。
你想要一個排序結果,因此
result = sort cs
where
CS將元組,其中第一個元素是字符,第二個元素的列表是它出現的次數。
cs = counts "happy"
counts [] = []
counts (c:cs) = (c, length otherc + 1) : counts nonc where
(otherc, nonc) = partition (c==) cs
就是這樣。
有趣的是,計數適用於任何支持==運算符的項目列表。
import Data.Array (Ix, accumArray, assocs)
eltDist :: (Bounded a, Ix a, Eq b, Num b) => [a] -> [(a, b)]
eltDist str = filter ((/=0) . snd) $
assocs (accumArray (+) 0 (minBound, maxBound) [(i, 1) | i <- str])
「minBound」和「maxBound」將取決於爲i推斷的類型的範圍。對於字符它將是0 - 1,114,111,這是奢侈的,但不是不可能的。如果您計算Unicode字符,這將特別方便。如果你只對ASCII字符串感興趣,那麼(0,255)就可以。數組的一個好處是它們可以被任何可以映射到整數的類型索引。請參閱1x。
assocs將索引和計數從數組中排列成對的列表並對未使用的列表進行過濾處理。
使用列表理解,不需要任何導入或排序。
[ (x,c) | x<-['A'..'z'], let c = (length.filter (==x)) "happy", c>0 ]
結果:
[('a',1),('h',1),('p',2),('y',1)]
上面是過濾和重寫(僅適用於字符計數> 0):
[(x,(length.filter (==x)) "happy") | x<-['A'..'z']]
說明:
我喜歡這個!當你只對某些字符的頻率感興趣而不是輸入字符串中的所有字符時,這非常有用。井井有條。 –
你必須先解決輸入支付像'「糊狀」'案件其中'p'的出現不是連續的。 – hammar
謝謝,修正。 :-) –
並注意'(\ x - >(head x,length x))== head &&& length',其中'(&&&)'來自'Control.Arrow'。 – Conal