动态规划
最长公共子序列问题
令A=a1,a2…an, B=b1,b2…bm, L[i, j]表示a1,a2…ai和b1,b2…bj的最长公共子序列长度。那么最重要的就是LCS(Longest Common Subsequence)的递推公式:
算法的伪代码如下所示:
算法的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)
运行结果如下图所示: