问题描述:
给定两个序列X,Y,输出两个序列的最长公共子序列。
动态规划求解
import numpy
def Longest_Common_Subsequence(X,Y):
"""
:param X: 序列X
:param Y: 序列Y
:return: X和Y的最长公共子序列
"""
# 序列长度
n = len(X)
m = len(Y)
# 初始化,新建二维数组C[0...n,0...m]和rec[0...n,0...m]
C = [[0 for i in range(m + 1)] for j in range(n + 1)]
rec = [[0 for i in range(m)] for j in range(n)]
# 动态规划
# 依次计算子问题
for i in range(0, n):
for j in range(0, m):
if X[i] == X[j]: # 末尾相等
# 记录长度和决策
C[i + 1][j + 1] = C[i][j]+1
rec[i][j] = "LU"
# 末尾不等
elif C[i][j + 1] >= C[i + 1][j]:
C[i + 1][j + 1] = C[i][j + 1]
rec[i][j] = "U"
else:
C[i + 1][j + 1] = C[i + 1][j]
rec[i][j] = "L"
# 倒序追踪方案
def Print_LCS(rec, X, i, j):
"""
:param rec: 追踪数组rec
:param X: 序列X
:param i: 当前位置i
:param j: 当前位置j
:return: X[1...i]和Y[1...j]的最长公共子序列
"""
if i <0 or j < 0:
return None
if rec[i][j] == "LU":
Print_LCS(rec, X, i-1, j-1)
print(X[i], end=",")
elif rec[i][j] == "U":
Print_LCS(rec, X, i-1, j)
else:
Print_LCS(rec, X, i, j-1)
return f"{Print_LCS(rec, X, i, j)}\n最长公共子序列长度记录表:\n{numpy.asmatrix(C)}\n追踪记录表:\n{numpy.asmatrix(rec)}"
if __name__ == '__main__':
X = ["A", "B", "C", "B", "D", "A", "B"]
Y = ["B", "D", "C", "A", "B", "A"]
print(Longest_Common_Subsequence(X, Y))