显示在haskell中重复的单词列表

时间:2008-12-31 06:01:05

标签: string parsing haskell

我需要能够编写一个函数来显示字符串中重复的单词并按顺序返回字符串列表并忽略非字母

例如在拥抱提示

repetitions :: String -> [String]

repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name  name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]

4 个答案:

答案 0 :(得分:8)

要将字符串拆分为单词,请使用words函数(在Prelude中)。 要使用filter消除Data.Char.isAlphaNum非单词字符。 将列表与其尾部一起压缩以获得相邻的对(x, y)。 折叠列表,建立一个新列表,其中包含x == x所有y

喜欢:

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
  where l = map (filter isAlphaNum) (words s)

我不确定这是否有效,但它应该给你一个粗略的想法。

答案 1 :(得分:2)

我是这种语言的新手,所以我的解决方案在Haskell退伍军人看来可能是一种丑陋,但无论如何:

let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') x)))))

此部分将删除字符串 s 中的所有非字母和非空格:

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') s

这个会将字符串 s 拆分为单词并将相同的单词组合成列表返回列表列表:

List.group (words s)

当此部分删除所有少于两个元素的列表时:

filter (\x -> (length x) > 1) s

在我们将所有列表连接到一个列表之后,通过

删除一个元素
concat (map tail s)

答案 2 :(得分:0)

这可能是不合理的,但它在概念上非常简单。我假设它正在寻找像示例一样的连续重复单词。

-- a wrapper that allows you to give the input as a String
repititions :: String -> [String]
repititions s = repititionsLogic (words s)
-- dose the real work 
repititionsLogic :: [String] -> [String]
repititionsLogic [] = []
repititionsLogic [a] = []
repititionsLogic (a:as) 
    | ((==) a (head as)) = a : repititionsLogic as
    | otherwise = repititionsLogic as

答案 3 :(得分:0)

以Alexander Prokofyev的回答为基础:

repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))

删除不必要的括号:

repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))

使用$删除更多的括号(如果结束括号位于表达式的末尾,则每个$可以替换左括号):

repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x

使用Data.Char中的函数替换字符范围,合并concat和map:

repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

使用剖面并以无点样式进行曲线处理以简化(\x -> length x > 1) to ((>1) . length)。这会将length与(&gt; 1)(部分应用的运算符或部分)组合在一个从右到左的管道中。

repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

消除显式“x”变量以使整个表达式无点:

repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)

现在,从右到左阅读的整个函数是一个管道,它只过滤字母或分隔符,将其拆分为单词,将其分成组,过滤那些具有多于1个元素的组,然后减少剩余的组每个人的第一个元素。