最长公共子序列
子序列:
一个序列的子序列是该序列删除若干个元素后得到的序列。例如“ACBD"和”BDF“都是”ABCDFEG“的子序列
最长公共子序列:
给定两个序列X,Y,求X和Y长度最长的公共子序列。
例如,”ABBCBDE“ "DBBCDB" 最长子序列为 ”BBCD“
def lcs_lenth(x, y):
m = len(x)
n = len(y)
c = [[0 for _ in range(n+1)] for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if x[i-1] == y[j-1]:
c[i][j] = c[i-1][j-1] + 1
else:
c[i][j] = max(c[i][j-1], c[i-1][j])
return c
def lcs(x, y):
m = len(x)
n = len(y)
c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
# 1 来自左上方, 2来自上方, 3 来自左方
b = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
for i in range(1, m+1):
for j in range(1, n+1):
if x[i-1] == y[j-1]:
c[i][j] = c[i-1][j-1] + 1
b[i][j] = 1
# b[i][j] = '↖'
elif c[i-1][j] > c[i][j-1]:
c[i][j] = c[i-1][j]
b[i][j] = 2
# b[i][j] = '↑'
else:
c[i][j] = c[i][j-1]
b[i][j] = 3
# b[i][j] = '←'
return c, b
def lcs_traceback(x, y):
c, b = lcs(x, y)
i = len(x)
j = len(y)
res = []
while i>0 and j>0:
if b[i][j] ==1:
res.append(x[i-1])
i -= 1
j -= 1
elif b[i][j] == 2:
i -= 1
else:
j -= 1
return ''.join(reversed(res))
print(lcs_traceback('ABCBDAB', 'BDCABA'))