[算法] 动态规划算法解最长公共子序列LCS问题
算法导论15章
不用数组:
def LCS(S1, S2, x, y):
if (x == -1) or (y == -1):
return 0
if S1[x] == S2[y]:
return 1 + LCS(S1, S2, x-1, y-1)
return max(LCS(S1, S2, x, y-1), LCS(S1, S2, x-1, y))
print(LCS('ABCBDAB', 'BDCABA', 6, 5))
使用二维数组:
# O(mn)
def LCS_length(X, Y):
m = len(X)
n = len(Y)
c = [[0 for i in range(n+1)] for i in range(m+1)]
for i in range(m):
for j in range(n):
if X[i] == Y[j]:
c[i+1][j+1] = c[i][j]+1
else:
c[i+1][j+1] = max(c[i+1][j], c[i][j+1])
return c
# O(m+n)
def print_LCS(c, X, i, j):
if i == 0 or j == 0:
return
if c[i][j] == c[i-1][j-1]+1:
print_LCS(c, X, i-1, j-1)
print(X[i-1])
elif c[i][j] == c[i-1][j]:
print_LCS(c, X, i-1, j)
else:
print_LCS(c, X, i, j-1)
X = 'ABCBDAB'
Y = 'BDCABA'
c = LCS_length(X, Y)
print('\n'.join([str(row) for row in c]))
print_LCS(c, X, len(X), len(Y))
应用场景
LCS与GST的一个重要区别就是LCS得到的最大公共子串是严格有序的, 对于一些顺序调换的情况, 它计算出的相似度是比较低的, 相反, GST并不要求其子串严格有序, 只要存在相等子串, 即使位置不对也可找到, 因此相对来说, 它计算出的相似度更高.
在分析生物学领域, DNA分子常被表示成一个字符串, 两个DNA分子之间的相似性常用它们共同包含的碱基对的序列长度来度量, 这是最长公共子序列应用最广泛的领域, LCS还可以应用于数据压缩、文件比较、语言识别等方面. GST算法在信息检索、文本编辑、信息提取等领域有重要的应用.