Python 最长公共子序列的界

Python 最长公共子序列的界,python,Python,我需要找到递归最长公共子序列问题的最紧界(最坏情况下)(只有它的长度)。我的意思是用m和n表示的复杂度界,m是字符串s的长度,n是字符串t的长度。有人能帮我吗 代码是: def lcs_len_v1(s, t): n = len(s) m = len(t) return lcs_len_rec(s,n,t,m) def lcs_len_rec(s,size_s,t,size_t): if size_s==0 or size_t==0: #if one of

我需要找到递归最长公共子序列问题的最紧界(最坏情况下)(只有它的长度)。我的意思是用m和n表示的复杂度界,m是字符串s的长度,n是字符串t的长度。有人能帮我吗

代码是:

def lcs_len_v1(s, t): 
    n = len(s)
    m = len(t)
    return lcs_len_rec(s,n,t,m)

def lcs_len_rec(s,size_s,t,size_t):

    if size_s==0 or size_t==0: #if one of the strings is empty
        return 0

    if s[0] == t[0]: #if we find a common char
        return lcs_len_rec(s[1:],len(s[1:]), t[1:],len(t[1:]))+1
    else:
        return max(lcs_len_rec(s,len(s),t[1:],len(t[1:])), lcs_len_rec(s[1:],len(s[1:]),t,len(t)))

我想这会管用的。但我也认为它对于长字符串来说是缓慢的

def max_common_str_len(s, t):
     if len(s) > len(t):
         return max_common_str_len(t, s)
     for length in range(len(s),0,-1):
         for offset in range(len(s)-length+1):
             if s[offset:offset+length] in t:
                 return length
     else:
         return 0

max_common_str_len('there is a house in new orleans', 'this is a house')
输出

11
编辑

11
我还试用了你的代码。我认为中等字符串的速度较慢,因为您的函数使用相同的参数调用
lcs\u len\u rec
-函数。考虑使用装饰器缓存/记忆它:

import functools

@functools.lru_cache(maxsize=None)
def lcs_len_rec(###your code###

这是我能够用Python编写的最快的实现:

def lcs(x, y):
    '''returns the length of longest common subsequence of x and y.
       >>> lcs('abcde','aebd')
       3
    '''
    s_x, s_y = len(x), len(y)
    if s_x>s_y: 
        x, y = y, x
        s_x, s_y = s_y, s_x
    y_previous = s_x*[0]
    for y_char in y:
        left_value = 0
        diagonal_value = 0
        n=0
        for x_char in x:
            up_value = y_previous[n]
            if y_char==x_char:
                left_value = diagonal_value+1
            else:
                if left_value<up_value: 
                    left_value = up_value 
            diagonal_value = up_value
            y_previous[n] = left_value 
            n+=1
    return y_previous[-1]
def lcs(x,y):
''返回x和y的最长公共子序列的长度。
>>>lcs(‘abcde’、‘aebd’)
3.
'''
s_x,s_y=len(x),len(y)
如果s_x>s_y:
x、 y=y,x
s_x,s_y=s_y,s_x
y_previous=s_x*[0]
对于y中的y_字符:
左_值=0
对角线_值=0
n=0
对于x中的x_字符:
上一个值=y上一个[n]
如果y_char==x_char:
左_值=对角线_值+1
其他:
如果左_值_y:
x、 y=y,x
s_x,s_y=s_y,s_x
cdef int i
temp_y_previous=s_x*[0]
cdef int*y_上一个
y_previous=malloc(s_x*cython.sizeof(int))
如果y_previous为空:
提高内存错误()
对于x范围内的i(s_x):
y_上一个[i]=临时y_上一个[i]
cdef char*cx
cx=malloc(s_x*cython.sizeof(char))
如果cx为空:
提高内存错误()
i=0
对于x中的字符:
cx[i]=ord(字符)
i+=1
cdef字符*cy
cy=malloc(s_y*cython.sizeof(char))
如果cy为空:
提高内存错误()
i=0
对于y中的字符:
cy[i]=ord(字符)
i+=1
cdef int k=0
cdef int left_值
cdef int对角线_值
cdef int n
cdef str y_char
cdef str x_char

kI认为将字符串及其长度传递给
lcs\u len\u rec
很奇怪。如果您在函数的第一行设置
size\s,size\u t=len(s),len(t)
,并划掉参数size\s和size\t,您的实现将不起作用,因为max\u common\u str_len(“在新奥尔良有一所房子”,“这是一所房子”)是13:)子序列是“th is a house”@在我看来,最大的公共字符串是连续字符串。因此,我的子序列实际上是“是一座房子”(有前导空间)。我假设这就是要求的。哦,是的,如果它是最大公共字符串,那么它是正确的,对不起:)