Haskell词汇的实现

问题描述 投票:3回答:2

我试图从Data.List中实现单词函数,但我的实现并没有完全按照我的意愿工作。

例如,如果函数的输入是 "tere vana kere",那么输出是["vana", "kere"],并且漏掉了第一个单词。但是当我在输入 "tere vana kere "前面加上空格时,输出是正确的["tere", "vana", "kere"]。

谁能指出这个问题。谢谢您

words' :: String -> [String]
words' xs = snd $ foldr (\x acc -> if isSpace x then 
                                    if null (fst acc) then
                                        acc
                                    else
                                        ([], (fst acc): (snd acc)) 
                               else 
                                     (x:fst acc, snd acc)   
                               ) ([],[]) xs
haskell words fold
2个回答
3
投票

好了,我们来试试这个。

step x acc =
  if isSpace x
    then
      if null (fst acc)
        then acc
        else ([], (fst acc) : (snd acc))
    else (x : fst acc, snd acc)

words' xs = snd $ foldr step ([], []) xs

现在让我们一步一步的来演练一下: 假设我们要 words' "ABC DEF GHI". 我们可以这样做。

Prelude> step 'I' ([], [])
("I", [])
Prelude> step 'H' it
("HI", [])
Prelude> step 'G' it
("GHI", [])
Prelude> step ' ' it
("", ["GHI"])
Prelude> step 'F' it
("F", ["GHI"])
Prelude> step 'E' it
("EF", ["GHI"])
Prelude> step 'D' it
("DEF", ["GHI"])
Prelude> step ' ' it
("", ["DEF","GHI"])
Prelude> step 'C' it
("C", ["DEF","GHI"])
Prelude> step 'B' it
("BC", ["DEF","GHI"])
Prelude> step 'A' it
("ABC", ["DEF","GHI"])
Prelude> snd it
["DEF","GHI"]

你看到这里的问题了吗?

问题是,只有当你看到一个空格字符时,你才会将当前的单词 "刷新 "到单词列表中。特别是,你 不要 当你看到输入端时,就会刷新。你可以通过替换 snd:

words' xs = (\ (w, ws) -> w:ws) $ foldr step ([], []) xs

顺便说一下,恭喜你让代码正确处理了多个连续的空格。 :-)

EDIT: 为了保留这个好的属性

words' xs = (\ (w, ws) -> if null w then ws else w:ws) $ ...

0
投票

关于上面的回答: 与其在字符串的末尾用单独的检查来刷新当前的单词, 为什么不在字符串的开头加上一个空格.

step x acc =
  if isSpace x
    then
      if null (fst acc)
        then acc
        else ([], (fst acc) : (snd acc))
    else (x : fst acc, snd acc)

words' xs = snd $ foldr step ([], []) $ ' ':xs
© www.soinside.com 2019 - 2024. All rights reserved.