如何在Haskell中查找字符串中字符的频率?

Hag*_*123 19 haskell

如何计算字符串中字符的频率,然后以表格的形式输出它们?

例如,如果我输入单词"happy",结果将是

h 1  
a 1  
p 2  
y 1  
Run Code Online (Sandbox Code Playgroud)

如果这也可以按ASCII顺序排序,那就太棒了.

我知道我需要使用计数功能,任何其他提示将不胜感激.

编辑:所有的答案都很棒,只有我在Haskell的初学者,我实际上并不了解他们在做什么.

ham*_*mar 41

最简单的解决方案是使用a 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)]
Run Code Online (Sandbox Code Playgroud)

那么这里发生了什么?

我们的想法是Data.Map使用字符作为键并将频率作为值来构建(树图).

首先,我们获取输入字符串并使用a 1来表示每个字符的元组以指示一次出现.

?> [(c, 1) | c <- input]
[('h',1),('a',1),('p',1),('p',1),('y',1)]
Run Code Online (Sandbox Code Playgroud)

接下来,我们使用fromListWith通过将每个键值对重复插入地图来从这些键值对构建有序映射.我们还给它一个函数,当一个键已经在地图中时将使用它.在我们的例子中,我们使用(+)这样的方式,当多次看到一个字符时,我们将计数添加到现有的总和中.

最后,我们将地图转换回使用的键值元组列表toList.

  • 为了记录,GHCi提示的标志是">"字符.当你第一次启动ghci时,你可能会看到`Prelude>`; 请注意,提示中列出了范围内的模块.哈马尔的ghci提示似乎被拉黑了. (4认同)

Mic*_*ohl 10

可能会有更短的东西,但这有效:

Prelude> import Data.List
Prelude Data.List> map (\x -> (head x, length x)) $ group $ sort "happy"
[('h',1),('a',1),('p',2),('y',1)]
Run Code Online (Sandbox Code Playgroud)

  • 并注意`(\ x - >(head x,length x))== head &&& length`,其中`(&&&)`来自`Control.Arrow`. (2认同)

Mar*_*riy 5

func xs = map (\a -> (head a, length a)) $ group $ sort xs