Python LCS递归函数的最大递归

Python LCS递归函数的最大递归,python,recursion,lcs,Python,Recursion,Lcs,我正在尝试执行一个LCS函数,该函数利用递归为我提供LCS有效的位置数,以及此处描述的LCS位置: input: LCS("smile", "tile") output: [3, "##ile", "#ile"] 每当我尝试执行它时,它都会告诉我有一个递归错误,如下所示: RecursionError: maximum recursion depth exceeded in comparison 我的代码有什么问题?我试图通过递归替换LCS不适用的区域,但是函数在哪里超出了它的深度 def

我正在尝试执行一个LCS函数,该函数利用递归为我提供LCS有效的位置数,以及此处描述的LCS位置:

input: LCS("smile", "tile")
output: [3, "##ile", "#ile"]
每当我尝试执行它时,它都会告诉我有一个递归错误,如下所示:

RecursionError: maximum recursion depth exceeded in comparison
我的代码有什么问题?我试图通过递归替换LCS不适用的区域,但是函数在哪里超出了它的深度

def LCS(s1, s2):
    if s1 == "" or s2 == "":
        return 0
    else:
        if s1[0] == s2[0]:
            s1 = s1 + s1[0]
            s2 = s2 + s2[0]
            count = 1 + LCS(s1[1:], s2[1:])
        else: 
            s1 = s1 + '#'
            count = max(LCS(s1, s2[1:]), LCS(s1[1:], s2))
    array = [count] + [s1] + [s2]
    print(array)

在第一次递归调用(
count=1+LCS(s1[1:],s2[1:])
)中,由于您刚刚在
s1
s2
的末尾添加了一个元素,因此传递的字符串大小与调用中的字符串大小相同,因此在终止方面没有任何进展


max
内部,第二个递归调用有相同的问题:您向
s1
添加了一个元素,因此传递的字符串的大小与调用中的相同。

我对您的逻辑一点也不清楚:在每次迭代中,您要么将第一个字符移动到字符串的末尾,或者删除它并附加一个#。 在这个过程中,唯一的缩减步骤是缩短较低分支中的s2,但在到达该分支之前,您将陷入无限递归。我在例程的顶部添加了一个简单的跟踪打印:

def LCS(s1, s2):
    print("ENTER s1=", s1, "\ts2=", s2)
下面是它被卡住的原因:

ENTER s1= smile     s2= tile
ENTER s1= smile#    s2= ile
ENTER s1= smile##   s2= le
ENTER s1= smile###  s2= e
ENTER s1= smile####     s2= 
ENTER s1= mile####  s2= e
ENTER s1= mile#####     s2= 
ENTER s1= ile#####  s2= e
ENTER s1= ile######     s2= 
ENTER s1= le######  s2= e
ENTER s1= le#######     s2= 
ENTER s1= e#######  s2= e
ENTER s1= #######e  s2= e
ENTER s1= #######e#     s2= 
ENTER s1= ######e#  s2= e
ENTER s1= ######e##     s2= 
ENTER s1= #####e##  s2= e
ENTER s1= #####e###     s2= 
ENTER s1= ####e###  s2= e
ENTER s1= ####e####     s2= 
ENTER s1= ###e####  s2= e
ENTER s1= ###e#####     s2= 
ENTER s1= ##e#####  s2= e
ENTER s1= ##e######     s2= 
ENTER s1= #e######  s2= e
ENTER s1= #e#######     s2= 
ENTER s1= e#######  s2= e
ENTER s1= #######e  s2= e


当运行失败时,需要将s2重置为其原始值。您当前的代码在每个字符串上多加一个字符进行备份,使s2在其最后一个字符和NULL之间永久跳转。

如其他人所述,您正在向字符串变量添加一个字符,并在下一个递归调用中切掉一个字符。通过这种方式,总是会有具有初始长度的字符串的递归调用,从而导致无限递归

仔细观察,这是没有意义的:

    if s1[0] == s2[0]:
        s1 = s1 + s1[0]
在这里,您再次将第一个字符添加到字符串的末尾。这不可能是正确的

此外,该函数只能返回0(或
None
),而不能返回其他值。这也不可能是正确的。不管函数做什么,它都应该返回一个值

由于您对匹配字符的计数和两个原始字符串的
#
填充版本感兴趣,因此可以让函数返回三个值(一个列表),而不是一个值

然后,代码可以这样工作:

def LCS(s1, s2):
    if s1 == "" or s2 == "":
        return 0, '#' * len(s1), '#' * len(s2)
    else:
        if s1[0] == s2[0]:
            count, r1, r2 = LCS(s1[1:], s2[1:])
            return  count+1, s1[0] + r1, s2[0] + r2
        else:
            count1, r11, r12 = LCS(s1, s2[1:])
            count2, r21, r22 = LCS(s1[1:], s2)
            if count2 > count1:
                return count2, '#' + r21, r22
            else:
                return count1, r11, '#' + r12

print (LCS ('smile', 'tile'))
输出:

(3, '##ile', '#ile')
看它继续跑