我试图从Data.List实现word函数,但是我的实现无法完全按照我的期望进行。
例如,如果函数的输入为“ 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
最佳答案
好的,让我们尝试一下:
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
顺便说一句,恭喜您使代码正确处理了多个连续的空格。 :-)
编辑:要保留该不错的属性:
words' xs = (\ (w, ws) -> if null w then ws else w:ws) $ ...