最长公共子序列问题python实现

动态规划

最长公共子序列问题

令A=a1,a2…an, B=b1,b2…bm, L[i, j]表示a1,a2…ai和b1,b2…bj的最长公共子序列长度。那么最重要的就是LCS(Longest Common Subsequence)的递推公式:
最长公共子序列问题python实现_第1张图片
算法的伪代码如下所示:
最长公共子序列问题python实现_第2张图片
算法的python实现:
已知 A = ‘xyxxzxyzxy’,B = 'zxzyyzxxyxxz’求A,B的最长公共子序列的长度和对应的序列
代码实现如下:

import numpy as np
def len_lcs(A, B):
    #分别获取两个字符串的长度
    n = len(A)
    m = len(B)
    #定义一个(n+1)*(m+1)的数组
    L = np.zeros((n+1, m+1), dtype=np.int)
    for i in range(1, n+1):
        for j in range(1, m+1):
            if A[i-1] == B[j-1]:
                L[i, j] = L[i-1, j-1] + 1
            else:
                L[i, j] = max(L[i, j-1], L[i-1, j])
    return L[n, m], L

def value_lcs(L,A, B):
    #这里由于我们需要逆序寻找字符,所以我们采用栈的数据结构
    char_seqs = []
    idx_sqs = []
    print(L)
    i = len(A)
    j = len(B)
    while(i >=1 and j >=1):
        #最大值来自于上方
        if L[i, j] == L[i-1, j]:
            i -= 1
        #最大值来自于左方
        elif L[i, j] == L[i, j-1]:
            j -= 1
        else:
            i -= 1
            j -= 1
            char_seqs.append(A[i])
            idx_sqs.append(i)
            
    s = ''
    for i in range(len(char_seqs)-1, -1, -1):
        s += char_seqs[i]
    print(idx_sqs)
    return s

if __name__ == '__main__':
    A = 'xyxxzxyzxy'
    B = 'zxzyyzxxyxxz'
    lcs, L = len_lcs(A, B)
    print(lcs)
    seqs = value_lcs(L, A, B)
    print(seqs)
运行结果如下图所示:

最长公共子序列问题python实现_第3张图片

你可能感兴趣的:(算法设计技巧与分析,动态规划,最长公共子序列)