Python LCS递归函数的最大递归
我正在尝试执行一个LCS函数,该函数利用递归为我提供LCS有效的位置数,以及此处描述的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
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')
看它继续跑