📅  最后修改于: 2021-01-12 03:35:20             🧑  作者: Mango
最长的公共子序列问题是找到两个给定字符串中都存在的最长序列。
让我们考虑序列S = 1 ,s 2 ,s 3 ,s 4 ,…,s n >。
S上的序列Z =
假设X和Y是元素的有限集合上的两个序列。我们可以说,Z是X和Y的一个公共子序列,如果Z,X和Y的子序列。
如果给出一组序列,则最长的公共子序列问题是找到所有序列的最大长度的公共子序列。
最长的常见子序列问题是经典计算机科学问题,它是数据比较程序(例如diff-utility)的基础,并已在生物信息学中得到应用。版本控制系统(例如SVN和Git)也广泛使用它来协调对版本控制的文件集合所做的多个更改。
令X为长度为m的序列, Y为长度为n的序列。检查X的每个子序列是否是Y的子序列,并返回找到的最长的公共子序列。
X有2 m个子序列。测试序列是否为Y的子序列需要O(n)时间。因此,朴素的算法将花费O(n2 m )时间。
令X =
在此过程中,以行主要顺序计算表C [m,n],并计算另一个表B [m,n]以构造最佳解。
Algorithm: LCS-Length-Table-Formulation (X, Y)
m := length(X)
n := length(Y)
for i = 1 to m do
C[i, 0] := 0
for j = 1 to n do
C[0, j] := 0
for i = 1 to m do
for j = 1 to n do
if xi = yj
C[i, j] := C[i - 1, j - 1] + 1
B[i, j] := ‘D’
else
if C[i -1, j] ≥ C[i, j -1]
C[i, j] := C[i - 1, j] + 1
B[i, j] := ‘U’
else
C[i, j] := C[i, j - 1]
B[i, j] := ‘L’
return C and B
Algorithm: Print-LCS (B, X, i, j)
if i = 0 and j = 0
return
if B[i, j] = ‘D’
Print-LCS(B, X, i-1, j-1)
Print(xi)
else if B[i, j] = ‘U’
Print-LCS(B, X, i-1, j)
else
Print-LCS(B, X, i, j-1)
该算法将打印X和Y的最长公共子序列。
要填充表,外部for循环迭代m次,内部for循环迭代n次。因此,算法的复杂度为O(m,n) ,其中m和n是两个字符串的长度。
在此示例中,我们有两个字符串X = BACDB和Y = BDCB以找到最长的公共子序列。
遵循算法LCS-Length-Table-Formulation(如上所述),我们计算了表C(显示在左侧)和表B(显示在右侧)。
在表B中,我们分别使用对角线箭头,左箭头和上箭头而不是’D’,’L’和’U’。生成表B后,LCS由函数LCS-Print确定。结果是BCB。