即使基本案例是完美的,递归也不会终止

时间:2017-09-24 12:14:05

标签: python algorithm python-3.x recursion dynamic-programming

我一直在尝试this问题。我的想法是尝试所有可能的组合,如果它有效,那么我将继续进行记忆。但实际上递归并没有停止。这是我的算法。

这是我写的代码:

def min_edits(s1, s2):
    if len(s1) == 0 and len(s2) == 0:
        return 0
    elif len(s1) == 0 or len(s2) == 0:
        return float("inf")
    elif s1[0] == s2[0]:
        return 1 + min_edits(s1[1:], s2[1:])
    else:
        replace = min_edits(s2[0] + s1[1:], s2)  # Replace the first character of first string with that of second one
        insert = min_edits(s2[0] + s1, s2)  # Adds the first character of second string to first one
        delete = min_edits(s2[1:], s2)  # delete first character of first string
        return min(
            insert,
            replace,
            delete
        )


if __name__ == '__main__':
    tc = int(input())
    for i_tc in range(tc):
        input()
        (s1, s2) = input().split(" ")
        answer = min_edits(s1, s2)
        print(answer)

这是递归树:

在该递归树中,第一个分支是替换,第二个分支是插入,最后一个分支是删除

" _"表示只有一个字符串为空,函数返回无穷大。

因此我们可以清楚地看到树在所有情况下都会被终止。

但它仍然说超出最大递归深度。

请告诉我我哪里做错了。谢谢:))

Recursion tree

2 个答案:

答案 0 :(得分:1)

问题是参数的长度在每一步都没有减少,这对于到达基本情况的递归调用至关重要。在替换中,两个字符串的长度保持不变,并且在插入步骤中,一个字符串的长度实际上增加。

那么,替换,删除或插入是什么意思?例如,假设我们有字符串:

ABCD and DECD

然后,如果我们正在查看索引0,那么替换/删除呼叫将使我们留下BCD& ECD和插入将留给我们ABCD和& ECD,或BCD& DECD。使用这种方法,至少一个字符串的长度总是减少,因此我们保证达到基本情况。

编辑:基本案例,但是逻辑存在问题,所以我已经添加了解决问题的方法:

def min_edits(s1, s2):
if len(s1) == 0:
    return len(s2)
if len(s2) == 0:
    return len(s1)
elif s1[0] == s2[0]:
    return min_edits(s1[1:], s2[1:]) #characters match, no additional cost here
else:
    replace = min_edits(s1[1:], s2) + 1  # Insert into second string
    insert = min_edits(s1, s2[1:]) + 1  # Insert into first string
    delete = min_edits(s1[1:], s2[1:]) + 1  # replace/remove from both strings
    return min(
        insert,
        replace,
        delete
    )

答案 1 :(得分:0)

你猜不到递归的问题是错误的猜测。

在最后的其他部分,' delete = min_edits(s2 [1:],s2)'代码应该是' delete = min_edits(s1 [1:],s2)'。因为我们正在删除第一个字符串的第一个字符和剩余的字符串。

以下代码已正确终止。

else:
    replace = min_edits(s2[0] + s1[1:], s2)  # Replace the first character of first string with that of second one
    insert = min_edits(s2[0] + s1, s2)  # Adds the first character of second string to first one
    delete = min_edits(s1[1:], s2)  # delete first character of first string
    return min(
        insert,
        replace,
        delete
    )

但编辑成本的计算不合适。您可能希望将其移动到实际执行编辑操作的位置。有些事情如下。

else:
    replace = min_edits(s1[1:], s2[1:]) + 1  # If a replace operation is performed, then s1[0] == s2[0].  As, they have matched reduce the problem to match new strings s1[1:], s2[1:]
    insert = min_edits(s1, s2[1:]) + 1  # If an insert operation is performed @ s1, then s1[0] == s2[0]. As, they have matched reduce the problem to match new strings s1,s2[1:]
    delete = min_edits(s1[1:], s2) + 1  # If an insert operation is performed @ s1. Reduce the problem to match new strings s1[1:], s2

    return min(
        insert,
        replace,
        delete
    )

希望它有所帮助!