48 lines
1.1 KiB
Python
48 lines
1.1 KiB
Python
"""
|
|
最长公共子序列 (LCS) — 动态规划
|
|
比较两个序列的相似度
|
|
"""
|
|
|
|
def lcs_length(X, Y):
|
|
"""计算 LCS 长度并返回 DP 表"""
|
|
m, n = len(X), len(Y)
|
|
dp = [[0] * (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]:
|
|
dp[i][j] = dp[i - 1][j - 1] + 1
|
|
else:
|
|
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
|
|
|
|
return dp[m][n], dp
|
|
|
|
def lcs_backtrack(X, Y, dp):
|
|
"""回溯找出 LCS 序列"""
|
|
i, j = len(X), len(Y)
|
|
result = []
|
|
|
|
while i > 0 and j > 0:
|
|
if X[i - 1] == Y[j - 1]:
|
|
result.append(X[i - 1])
|
|
i -= 1
|
|
j -= 1
|
|
elif dp[i - 1][j] > dp[i][j - 1]:
|
|
i -= 1
|
|
else:
|
|
j -= 1
|
|
|
|
return ''.join(reversed(result))
|
|
|
|
if __name__ == "__main__":
|
|
X = "ABCBDAB"
|
|
Y = "BDCABB"
|
|
|
|
length, dp_table = lcs_length(X, Y)
|
|
lcs_str = lcs_backtrack(X, Y, dp_table)
|
|
|
|
print(f"序列 X: {X}")
|
|
print(f"序列 Y: {Y}")
|
|
print(f"LCS 长度: {length}")
|
|
print(f"LCS 序列: {lcs_str}")
|