算法设计与分析——最长公共子序列问题

题目描述:

简述最长公共子序列问题及求解方法。

设两个长度为n和m的字符串A和B

A=a1,a2,...an

B=b1,b2,...bn

令L[i,j]表示a1,a2,...ai和b1,b2,...bj的最长公共子序列的长度,则A和B最长公共子序列的关系递推式为:

image.png

例如,Z={b,c,d,b}是序列X={a,b,c,b,d,a,b}的子序列,相应的递增下标序列为{2,3,5,7}。给定2个序列X和Y,当另一个序列Z即是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。

例题:

image.png

B z x y y z x z
0 1 2 3 4 5 6 7
A 0 0 0 0 0 0 0 0 0
x 1 0 0 1 1 1 1 1 1
z 2 0 1 1 1 1 2 2 2
y 3 0 1 1 2 2 2 2 2
z 4 0 1 1 2 2 3 3 3
z 5 0 1 1 2 2 3 3 4
y 6 0 1 1 2 3 3 3 4
x 7 0 1 2 2 3 3 4 4

最长公共子序列:

xyzz
zyzz

代码实现(根据递推式记忆)

void LCSLength(char *x, char *y, int m, int n, int L[][MAXLEN])
{
    //字符串x长度为m,字符串y长度为n,L中存放最长公共子序列长度
    int i,j;
    for(i=0;i<=m;i++)
        L[i][0]=0;
    for(j=1;j<=n;j++)
        L[0][j]=0;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(x[i]==y[i])
            {
                L[i][j]=L[i-1][j-1]+1;  //记忆
            }
            else if(x[i]!=y[i])  //记忆
            {
                L[i][j]=L[i-1][j];
            }
            else
            {
                L[i][j]=L[i][j-1];
            }
        }
    }
    return L[m][n];  //记忆
}
原文地址:https://www.cnblogs.com/wangzheming35/p/15734243.html