动态规划之最长公共子序列
问题描述
序列可以理解成一个字符串,
比如『Chinese』就是一个序列,而子序列指的是由序列中的若干字符,
按原相对次序构成的序列。需要注意的是,子序列中的各个字符的相对次序一定和原来序列中的相对次序一样。
比如,『Cin』是『Chinese』的子序列,而『sin』就不是『Chinese』的子序列。
最长公共子序列(Longest Common Subsequence)问题,
就是要找出两个序列的最长的公共子序列。
假设有一个长度为n的序列A[1,n]和一个长度为m的序列B[1,m],A和B的最长公共子序列可以记为LCS(A, B)。
思路
对于序列A[0,n]和B[0,m],LCS(A, B)无非三种情况:
1.若n=-1或m=-1,则取作空序列("");
2.若A[n] = 'X' = B[m],则取作LCS(A[0,n-1], B[0,m-1]) + 'X';
3.若A[n] ≠ B[m],则取在LCS(A[0,n], B[0,m-1])和LCS(A[0,n-1], B[0,m])中取更长者。
def getLCS(str1, str2):
str1_len = len(str1)
str2_len = len(str2)
c = [[0 for i in range(str2_len+1)] for i in range(str1_len+1)]
lcs = ''
for i in range(1, str1_len + 1):
haveSame = False
sameChar = ''
for j in range(1, str2_len + 1):
if str1[i-1] == str2[j-1]:
c[i][j] = c[i-1][j-1] + 1
haveSame = True
sameChar = str1[i-1]
else:
c[i][j] = c[i][j-1] if c[i][j-1] > c[i-1][j] else c[i-1][j]
if haveSame and c[i][j] == len(lcs) + 1:
lcs += sameChar
return lcs
str1 = 'didactiC'
str2 = 'advant'
print(getLCS(str1, str2))