繁体   English   中英

使用递归检查字符串是否与其他两个给定字符串交错

[英]Check if a string is interleaving of two other given strings using recursion

我想检查 s3 是否是 s1 和 s2 的有组织组合。 所以我写了这个:

def organized_comp(s1,s2,s3):
    l1, l2, l3 = len(s1), len(s2),len(s3)
    if (l1 == 0 and l2 == 0 and l3 ==0):
        return True
    if (l1 == 0 and s2 == s3) or (l2 == 0 and s1 == s3):
        return True
    if (l3 != (l1 +l2)) or (l3 == 0 and (l1 > 0 or l2 > 0)):
        return False    
    if s1 and s1[0] == s3[0]:
        return True and organized_comp(s1[1:], s2, s3[1:])
    if s2 and s2[0] == s3[0]:
        return True and organized_comp(s1, s2[1:], s3[1:])

当我发送:s1 = "ABZ", s2 = "ABAXZ", s3 = "ABAXABZZ" 它返回 False,它需要返回 True。 我想我知道问题所在——因为 s1[0] = s2[0] 并且它总是以 s1 开头(如果我发送 s2 = "ABZ", s1 = "ABAXZ" 它有效)。

我该如何纠正?

您对问题的分析是正确的:如果s1[0] == s2[0] ,那么您不知道应该使用哪个字符。 因此,您应该尝试这两种可能性,如果其中至少一种可行,则返回 True。

这可以通过逻辑运算符or来完成。

另请注意,您的“如果森林”缺少应该返回 False: when l1 + l2 == l3 but s3[0] not in (s1[0], s2[0])的情况。 In python, as opposed to almost every other programming language, if a return is missing in a function, python doesn't crash and the function silently returns None as if there had been an explicit return None . 因此,按照您编写它的方式, organized_comp('a', 'b', 'c')将返回None而不是False

您的某些条件有点多余,例如以下两个条件是等效的:

(l3 != (l1 +l2)) or (l3 == 0 and (l1 > 0 or l2 > 0))
(l3 != (l1 +l2)) # if the second part was True, then the first part would be True anyway

这是一个建议的修复:

def organized_comp(s1,s2,s3):
    l1, l2, l3 = len(s1), len(s2),len(s3)
    return (l3 == l1 + l2) and (
        (l3 == 0) or
        (l1 > 0 and s3[0] == s1[0] and organized_comp(s1[1:], s2, s3[1:])) or
        (l2 > 0 and s3[0] == s2[0] and organized_comp(s1, s2[1:], s3[1:]))
    ) 

在评论中发现,OP 需要一个无需replace的解决方案

无需replace的解决方案:

s1 = "ABZ"
s2 = "ABAXZ"
base = "ABAXABZZ"

def is_combination_of(base: str, p1: str, p2: str):
    if len(base) > 0:
        try:
            p1i = p1.index(base[0])
            return is_combination_of(base[1:], p1[:p1i] + p1[p1i+1:], p2)
        except ValueError:
            pass
        try:
            p2i = p2.index(base[0])
            return is_combination_of(base[1:], p1, p2[:p2i] + p2[p2i+1:])
        except ValueError:
            pass
    if base == p1 == p2 == '':
        return True
    return False

print(is_combination_of(base, s1, s2))

您的错误是假设对于s3中的每个第一个字符,您可以找到该字符作为s1s2的第一个字符。 对于这种简化的情况,这种方法失败了:

s1 = 'CA'
s2 = 'CB'
s3 = 'ABCC'

如您所见,您需要查看s1s2的所有字符,以确定s3[0]是否在其中。

对于这种确切的情况,递归方法是不必要的,但如果你愿意,可以这样做:

s1 = "ABZ"
s2 = "ABAXZ"
base = "ABAXABZZ"

def is_combination_of(base: str, p1: str, p2: str):
    if len(base) > 0:
        if base[0] in p1:
            return is_combination_of(base[1:], p1.replace(base[0], '', 1), p2)
        if base[0] in p2:
            return is_combination_of(base[1:], p1, p2.replace(base[0], '', 1))
    if base == p1 == p2 == '':
        return True
    return False

print(is_combination_of(base, s1, s2))

但这是一种非常低效的方法。 我的意思是,使用递归。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM