使用haskell计算每个单词重复的次数

296*_*349 2 haskell functional-programming

我是 Haskell 和函数式编程的新手...

我想将函数作为字符串传递,并计算每个语法(如(if、else、elseif for、while、dowhile)在使用haskell 的函数中存在的次数。

例如,如果给出这样的输入

if(i=0){  for(i=0;i<num;i++){if(name== name)}
}elseif (i=3){for(i=3;i<num;i++){}}
else{while (i>3){name = name; i--;}}
Run Code Online (Sandbox Code Playgroud)

我期待输出。(它必须给出每个语法出现的次数)

[(if,2),(for,2),(elseif,1),(else,1),(while,1)]
Run Code Online (Sandbox Code Playgroud)

我已经完成了编码。如下所示

import Control.Arrow

syntaxCount :: String -> [(String, Int)]
syntaxCount = map (head &&& length) . group .sort  . words
Run Code Online (Sandbox Code Playgroud)

此功能有效,但它显示的结果是这样的。

[("(i=3){for(i=3;i<num;i++){}}",1),("(i>3){name",1),("=",1),("else{while",1),("for(i=0;i<num;i++){if(name==",1),("i--;}}",1),("if(i=0){",1),("name)}",1),("name;",1),("}elseif",1)]
Run Code Online (Sandbox Code Playgroud)

谁能帮我摆脱所有不需要的东西并得到这样的结果..

[(if,2),(for,12),(elseif,1),(else,1),(while,1)]
Run Code Online (Sandbox Code Playgroud)

Chr*_*lor 5

我将其拆分为一个函数,该函数生成输入字符串中的关键字列表,以及一个计算列表中不同元素的函数

import Data.Char
import Control.Arrow

keywords :: String -> [String]
keywords = words . map (\x -> if isAlpha x then x else ' ')

count :: Ord k => [k] -> [(k,Int)]
count = map (head &&& length) . group . sort
Run Code Online (Sandbox Code Playgroud)

然后你可以定义syntaxCount为一个简单的组合

syntaxCount = count . keywords
Run Code Online (Sandbox Code Playgroud)

例如

>> let inp = "if(i=0){  for(i=0;i<num;i++){if(name== name)}\n}elseif (i=3){for(i=3;i<num;i++){}}\nelse{while (i>3){name = name; i--;}}"
>> syntaxCount inp
[("else",1),("elseif",1),("for",2),("i",10),("if",2),("name",4),("num",2),("while",1)]
Run Code Online (Sandbox Code Playgroud)

如果您只想包含一组特定的关键字,那么您应该明确过滤它们

import qualified Data.Set as Set

allKeywords :: Set.Set String
allKeywords = Set.fromList ["if", "else", "elseif", "for", "while"]

keywords = filter (`Set.member` allKeywords) . words . map removePunc
  where removePunc c = if isAlpha c then c else ' '
Run Code Online (Sandbox Code Playgroud)