递归函数,用于标识字符串1是否包含在字符串2中?

Recursive function that identifies whether string 1 is contained within string 2? (Python 3.4)

如果第一个字符串中的所有字符都可以按顺序在第二个字符串中找到,那么是否有方法编写一个以两个字符串为参数并返回true的递归(必需)函数;否则返回false?

例如:

1
2
3
4
5
6
7
8
>>> contains("lit","litter")
True
>>> contains("thot","thurtle")
False
>>> contains("ratchet","ramtbunchiousest")
True
>>> contains("shade","hadsazie")
False

字母不需要是连续的(如第三个例子),但它们必须是有序的(这就是第四个例子失败的原因)。

我写了这个代码:

1
2
3
4
5
6
7
8
9
10
11
12
def contains_recursive(s1, s2):

if s1 =="":
    return True
elif s1[0] == s2[0]:
    return contains_recursive(s1[1:], s2[1:])
elif s1[0] != s2[0]:
    return contains_recursive(s1[0], s2[1:])
else:
    return False

return contains_recursive(s1, s2) == True

它给出了这个错误:

1
IndexError: string index out of range

我该怎么解决这个问题?


在该行:

1
 return contains_recursive(s1[0], s2[1:])

您正在将s1缩短为一个字符,但在下一个调用时,您可能会点击:

1
 return contains_recursive(s1[1:], s2[1:])

用s1表示len 1的字符串。

您需要使用:

1
return contains_recursive(s1, s2[1:])

加上对s1长度的检查


您得到的错误可能是因为s2是空字符串。还要加上一个长度检查。如果你达到这一点,这意味着你没有找到所有的字母,你正在寻找,因此,最终结果应该是错误的。

1
2
if s2 == '':
    return False


我认为递归是一种要求。在这种情况下:

1
2
3
4
5
6
7
8
def contains(s1, s2):
    if not s1:
        return True
    i = s2.find(s1[0])
    if i == -1:
        return False
    else:
        return contains(s1[1:], s2[i+1:])

这将产生:

1
2
3
4
5
6
7
8
>>> contains("lit","litter")
True
>>> contains("thot","thurtle")
False
>>> contains("ratchet","ramtbunchiousest")
True
>>> contains("shade","hadsazie")
False


为了提高效率,请避免使用救援功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def test(s1, s2):
    idx2 = 0
    for c in s1:
        if c in s2[idx2:]:
            idx2 = s2.index(c) + 1
        else:
            return False

    return True

# Test
lists = [   ("lit","litter"),
            ("thot","thurtle"),
            ("ratchet","ramtbunchiousest"),
            ("shade","hadsazie")]

result = [test(*t) for t in lists]
print(result)
# Output
[True, False, True, False]