序列的最长公共子序列算法

时间:23-06-23 网友

序列的最长公共子序列算法

最长公共子序列(Longest Common Subsequence,LCS)是求解两个序列的公共最长子序列,被广泛应用于压缩、寻找序列间的相似性、验证递归算法等方面。该算法采用动态规划的方式求解,时间复杂度为O(nm),其中n和m分别为两个序列的长度。

1、定义

序列A和B的最长公共子序列是指一个序列C,它是在A和B的所有子序列中最长的那个。例如,对于序列A=“AGCAT”和B=“GAC”, “GA”是它们的最长公共子序列。

2、求解

采用动态规划的方式求解,首先需要定义状态和状态转移方程。

状态:令L(i, j)表示序列A前i个字符和序列B前j个字符的最长公共子序列的长度。

状态转移方程:当A[i]=B[j]时,则L(i, j) = L(i -1, j -1) + 1;当A[i]不等于B[j]时,则L(i, j) = max{L(i - 1, j), L(i, j - 1)}。

其中,max{a, b}表示a和b的最大值。

代码实现:

int LCS(char* A,char *B,int lenA,int lenB){

int C[lenA+1][lenB+1];

for(int i=0;i<=lenA;i++){

for(int j=0;j<=lenB;j++){

if(i==0||j==0)

C[i][j]=0;

else if(A[i-1]==B[j-1])

C[i][j]=C[i-1][j-1]+1;

else

C[i][j]=max(C[i-1][j],C[i][j-1]);

}

}

return C[lenA][lenB];

}

3、优化

上述实现方法的时间复杂度为O(nm),能满足绝大部分应用的需求。但是,在某些条件下,可进行优化。

3.1 空间优化

上述实现方法会开辟一个长度为(n+1)×(m+1)的二维数组,空间复杂度为O(nm)。但是,实际上在计算C[i][j]时,只用到了C[i-1][j],C[i][j-1]和C[i-1][j-1]这三个元素。因此,可以用一个一维数组c[j]表示A[0~i-1]与B[0~j-1]的LCS。每次计算c[j]的值时,只需要使用之前计算的c[j-1]和C[j]的值即可,将二维数组优化为一维数组,空间复杂度为O(min(lenA,lenB))。

代码实现:

int LCS(char* A,char *B,int lenA,int lenB){

int C[min(lenA,lenB)+1];

memset(C,0,sizeof(C));

for(int i=1;i<=lenA;i++){

int last=0;

for(int j=1;j<=lenB;j++){

int tmp=C[j];

if(A[i-1]==B[j-1])

C[j]=last+1;

else

C[j]=max(C[j],C[j-1]);

last=tmp;

}

}

return C[lenB];

}

3.2 反向输出LCS

上述实现方法仅仅返回了最长公共子序列的长度,如果要输出该序列,需要进行进一步处理。可以采用反向输出法,从LCS最右端开始向左遍历,每当L(i,j)=max{L(i-1,j),L(i,j-1)}时,将A[i-1]和B[j-1]中较大的那个加入到结果序列中。

代码实现:

void PrintLCS(char* A,char* B,int lenA,int lenB,int** c){

if(lenA==0||lenB==0)

return;

if(A[lenA-1]==B[lenB-1]){

PrintLCS(A,B,lenA-1,lenB-1,c);

printf("%c",A[lenA-1]);

}else{

if(c[lenA-1][lenB]>c[lenA][lenB-1])

PrintLCS(A,B,lenA-1,lenB,c);

else

PrintLCS(A,B,lenA,lenB-1,c);

}

}

4、应用

最长公共子序列算法被广泛应用于:

压缩:在压缩数据时,如果两个字符串之间相似度高,就可以考虑使用它们的LCS作为公共部分,只保留前缀和后缀。

寻找序列间的相似性:在序列比对的过程中,可以通过求解两个序列的LCS,来寻找它们之间的相似性。

验证递归算法:一些递归算法实现时需要多次计算相同的子问题,LCS算法可以用来确定这样的重复计算是否可以优化。

5、总结

最长公共子序列算法是一种经典的算法,被广泛应用于压缩、序列比对和递归算法优化等领域。该算法采用动态规划的方式求解,时间复杂度为O(nm),可以进行一些优化,包括空间优化和反向输出LCS。

《序列的最长公共子序列算法》相关文档:

序列的最长公共子序列算法06-23

最长公共上升子序列(LCIS)的平方算法06-23

最长公共子序列长度06-23

最长公共子序列代码06-23

最长递增子序列06-23

最长公共子序列全部解06-23

最长公共子序列 二分优化06-23

最长公共子序列长度10-28

最长公共子序列代码11-23

序列的最长公共子序列算法12-17

Top