最长公共序列Python递归函数的长度

最长公共序列Python递归函数的长度,python,longest-substring,Python,Longest Substring,我试图用python中的递归实现这个函数,但我犯了一个错误。我不明白怎么了,你能帮我吗 守则: def LongestCommonSubsequence(X,Y,tailX,tailY): if tailX == tailY and tailX!='' and (X=='' or Y==''): return len(tailX) elif X=='' or Y=='': return 0 else: re

我试图用python中的递归实现这个函数,但我犯了一个错误。我不明白怎么了,你能帮我吗

守则:

def LongestCommonSubsequence(X,Y,tailX,tailY):
    if tailX == tailY and tailX!='' and (X=='' or Y==''):
            return len(tailX)
    elif X=='' or Y=='':
            return 0
    else:

        return max( LongestCommonSubsequence(X[1:],Y[1:],tailX+X[0],tailY+Y[0]),
                    LongestCommonSubsequence(X[1:],Y[1:],tailX+X[0],tailY),
                    LongestCommonSubsequence(X[1:],Y[1:],tailX,tailY+Y[0]),
                    LongestCommonSubsequence(X[1:],Y[1:],tailX,tailY)) 

X=raw_input() 
Y=raw_input() 
print LongestCommonSubsequence(X,Y,'','')
输入:

abccdabab 
bacdbeb 
预期产量:5

我得到的结果:4

您似乎在尝试优化常见的尾部字符串;如果两个字符串都以相同的尾部结尾,您确实可以跳过几个递归步骤

但实际上,你并不是在构建尾巴,而是在构建头部,即开头的角色

这是一个没有优化的递归llcs:

def llcs(xstr, ystr):
    if not xstr or not ystr:
        return 0
    x, xtail, y, ytail = xstr[0], xstr[1:], ystr[0], ystr[1:]
    if x == y:
        return 1 + llcs(xtail, ytail)
    return max(llcs(xstr, ytail), llcs(xtail, ystr))
通过比较从
xstr
ystr
开头删除字符的长度,找到最大最长公共子字符串长度,而不是两者

对于
max()
调用,您的代码从不将
X
Y[1://code>或
X[1://code>与
Y
配对,因此您永远不会在
X
Y
中找到该特定起始字符的LCS

然后,您可以通过查看
xtail
ytail
(实际尾部)来尝试优化,并提前退出:

def llcs(xstr, ystr):
    if not xstr or not ystr:
        return 0
    x, xtail, y, ytail = xstr[0], xstr[1:], ystr[0], ystr[1:]
    if x == y:
        if xtail == ytail:
            # if the tails match, bail out early
            return 1 + len(xtail)
        return 1 + llcs(xtail, ytail)
    return max(llcs(xstr, ytail), llcs(xtail, ystr))

X和Y总是字符串吗?如果它们是其他集合,例如列表,那么
elif X==''或Y=''
将始终为False。您可以利用布尔上下文固有的类型转换,只需执行
elif not X或not Y:
I将其复制到一个正常工作的LLCS实现中;它既适用于字符串,也适用于列表。如果希望重新打开此文件,请提供详细信息。请给出示例输入、预期输出、您得到的结果(包括错误消息)以及您自己认为问题所在的位置。就目前而言,这不是一个好问题。输入:abccdabab bacdeb预期输出:5我得到的:4这不是一个重复的问题,我还没有找到递归实现!我看不出这是怎么回事。。我不想找到最长的一个——我只是不想找到那个长度。@michaelkova:它是递归的,但我在递归调用名中打错了。返回的是长度,而不是实际的子字符串。对于您的示例输入,函数返回
5
。哦,好的,我以为您使用了lcs函数。好吧,它确实有用!非常感谢。你能解释一下为什么你的第一个实现是有效的吗?我很难理解。@michaelkova:拿一个网格,一根绳子放在顶部,另一根放在侧面。然后标记有匹配字符的所有单元格(即
x==y
大小写);然后,将最大长度创建为从左上角到右下角穿过栅格的路径,在该路径中只能向右或向下移动。递归只查看左上角的单元格,将表的其余部分视为递归调用,一个用于向右的步骤,一个用于向下的步骤,它将选择返回值最高的一个。@michaelkova:向右的步骤和向下的步骤作为子字符串实现;删除
x
的第一个字符是一个方向,删除
y
的第一个字符是另一个方向。