一、最长公共子序列概率
最长公共子序列(LCS)是指两个序列的最长子序列的问题,且子序列不需要在原序列中占用连续的位置 。如下图,序列ABCBDAB与序列BDCABA的最长子序列为BCBA,长度为4。
二、计算最长公共子序列
(一)子问题的界定
(二)子问题的依赖
(三)子问题递推方程
(四)递推时的标记函数
(五)子序列的回溯
三、最长公共子序列的实现
"""
@Author : heyw
@Contact : he_yuanwen@126.com
@Time : 2020/2/28 19:40
@Software: PyCharm
@FileName: LCS.py
"""
def LCS(str1, str2):
m = len(str1) + 1
n = len(str2) + 1
# 一、标记最长公共子序列
# 1.matrix[i][j]表示串str1的前i个字符和串str2的前j个字符的最长公共子串
matrix = [[["", 0] for _ in range(n)] for _ in range(m)]
# 2.初始化
for i in range(1, m):
matrix[i][0][0] = str1[i - 1]
for j in range(1, n):
matrix[0][j][0] = str2[j - 1]
# 3.递推
for i in range(1, m):
for j in range(1, n):
if str1[i - 1] == str2[j - 1]:
matrix[i][j] = ["↖", matrix[i - 1][j - 1][1] + 1]
elif matrix[i][j - 1][1] > matrix[i - 1][j][1]:
matrix[i][j] = ['←', matrix[i][j - 1][1]]
else:
matrix[i][j] = ['↑', matrix[i - 1][j][1]]
# 二、回溯最长公共子序列
i = m - 1
j = n - 1
subSequence = []
while i > 0 and j > 0:
if matrix[i][j][0] == '↖':
subSequence.append(matrix[i][0][0])
i -= 1
j -= 1
elif matrix[i][j][0] == '←':
j -= 1
elif matrix[i][j][0] == '↑':
i -= 1
subSequence.reverse()
return "".join(subSequence)
if __name__ == '__main__':
max_len_subSeq = LCS("ABCBDAB", "BDCABA")
print("最长公共子序列长度:{}".format(len(max_len_subSeq)))
print("最长公共子子串:{}".format(max_len_subSeq))
最长公共子序列长度:4
最长公共子子串:BCBA