我试图想出一个带有2个字符串参数的haskell函数。然后它检查第一个字符串是否包含第二个字符串作为子字符串。例如:“bring”包含子串“in”。如果传递“带”“输入”,则该函数应返回true。这是我到目前为止所做的,但它并没有真正起作用。部分工作。我不知道如何在递归情况下分配一个真值。
check::[Char]->[Char]->Bool
check [][] =False
check _[] =False
check []_ =False
check(x:xs)(y:ys)
| y==x =True
| otherwise =check xs (y:ys)
main = do
print $ check "bring" "in"
答案 0 :(得分:5)
根本没有使用库或酷技巧的直接实现可能是:
and you get the Result like this
这是天真子串搜索的“规范”方式(在任何编程语言中我猜?):对于字符串的每个后缀,检查子字符串是否是前缀。
请注意,substring参数位于字符串之前。
答案 1 :(得分:3)
它不起作用的原因是因为你似乎只匹配第二个字符串的第一个字符:
check::[Char]->[Char]->Bool
check [][] =False
check _[] =False
check []_ =False
check(x:xs)(y:ys)
| y == x =True -- this line
| otherwise =check xs (y:ys)
main = do
print $ check "bring" "in"
通过执行以下操作进行修复:
check::[Char]->[Char]->Bool
check l s = check' l s True where
check' _ [] h = True
check' [] _ h = False
check' (x:xs) (y:ys) h = (y == x && check' xs ys False) || (h && check' xs (y:ys) h)
main = do
print $ check "bring" "in"
另请注意,如前所述,空字符串是其自身的子集和任何非空字符串。额外的布尔值是快速消除当前搜索并再次从子字符串开始
最后,要成为一名优秀的程序员,我们可以通过以下方式使其成为通用:
check::Eq a => [a]->[a]->Bool
check l s = check' l s True where
check' _ [] h = True
check' [] _ h = False
check' (x:xs) (y:ys) h = (y == x && check' xs ys False) || (h && check' xs (y:ys) h)
main = do
print $ check "bring" "in"