我正在做这个练习:
给定一个短语,计算每个单词在该短语中出现的次数。
在本练习中,您可以期望单词始终为以下之一:
由一个或多个ASCII数字组成的数字(即“0”或“1234”)OR由一个或多个ASCII字母组成的简单单词(即“a”或“they”)OR由一个撇号连接的两个简单单词的缩写(即“it 's”或“they' re”)当计算单词时,您可以假设以下规则:
计数不区分大小写(即“You”、“you”和“YOU”是同一个单词的3次使用)。计数是无序的;测试将忽略单词和计数的排序方式除了缩写形式中的撇号之外,所有形式的标点符号都将被忽略。单词可以用任何形式的空格(即“\t”、“\n”、““)分隔。例如,对于短语“That 's the password:“密码123”!",特工喊道。\n所以我逃走了。计数应该是:
那就是:2.密码:2 123:1叫道:1.专项:1.代理:10:1 i:1逃跑了:1
我的代码:
module WordCount (wordCount) where
import qualified Data.Char as C
import qualified Data.List as L
import Text.Regex.TDFA as R
wordCount :: String -> [(String, Int)]
wordCount xs =
do
ys <- words xs
let zs = R.getAllTextMatches (ys =~ "\\d+|\\b[a-zA-Z']+\\b") :: [String]
g <- L.group $ L.sort [map (C.toLower) w | w <- zs]
return (head g, length g)
但是它在输入“one fish two fish red fish blue fish”时失败了,它为每个单词输出一个计数,即使是重复的单词,就好像排序和分组没有做任何事情一样。为什么?
我读过this answer,它使用Control.Arrow
以一种更高级的方式基本上做了同样的事情。
2条答案
按热度按时间iecba09b1#
您不需要使用
words
来拆分行,正则表达式应该可以实现所需的拆分:s2j5cfk02#
使用
words
将输入xs
按空格拆分为单词,使用绑定语句ys <- …
在单子列表中迭代这些单词,然后使用正则表达式将每个单词拆分为子词(在示例中,只有一个匹配项),并对列表中的每个子词进行排序和分组。我相信您基本上可以删除对
words
的初始调用: