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

时间:2014-01-06 17:30:59

标签: haskell functional-programming

我对Haskell和功能编程很新...

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

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

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--;}}

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

[(if,2),(for,2),(elseif,1),(else,1),(while,1)]
我完成了编码。如下图所示

import Control.Arrow

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

此功能有效,但会显示如下结果。

[("(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)]

任何人都可以帮助我摆脱所有不需要的东西并得到像这样的结果..

[(if,2),(for,12),(elseif,1),(else,1),(while,1)]

1 个答案:

答案 0 :(得分:4)

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

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

然后,您可以将syntaxCount定义为简单的合成

syntaxCount = count . keywords

例如

>> 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)]

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

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 ' '