最长公共子序列(LCS)问题(算法思想及代码)

(1)问题描述:输入:两个字符串X、Y,X=(x_{1},x_{2},...,x_{n})、Y=(y_{1},y_{2},...,y_{n});输出:Z=X和Y的最长公共子序列。

注释:

最长公共子串。如X=(a,b,d,a,c,b,a)、Y=(c,d,d,a,c,b),则最长公共子序列为Z=(d,a,c,b)。字符串的子序列是字符串的前缀。

(2)问题分析:

1.定义:设X=(x_{1},x_{2},...,x_{n})是一个序列,X的第i个前缀X_{i}是一个序列,定义为X_{i}=X=(x_{1},x_{2},...,x_{i})

2.优化解结构:

LCS_{XY}:表示前缀X、Y的最长公共子序列的长度

子问题具有重叠性:


采用动态规划策略。

3.递归方程的表示:

假设我们定义C[i,j]=前缀Xi和Yj的LCS的长度。

递归方程:

 4.计算过程

自底向上递归地计算代价

 代价矩阵帮助理解。

(3)c++代码实现:

#include <iostream>

using namespace std;
#define MAX_LEN 20//规定字符串的最大长度不超过20


int LCS-length(char* X,char *Y)
{
    int cause[MAX_LEN][MAX_LEN];
    int len1 = strlen(X);
    int len2 = strlen(Y);
    //对边界情况进行初始化
    for(int i=0;i<=len1;i++)
    {
        cause[i][0] = 0;
    }
    for(int j=0;j<=len2;j++)
    {
        cause[0][j] = 0;
    }
    //两个for循环实现自底向上计算代价
    for(i=1;i<=len1;i++){
        for(j=1;j<=len2;j++){
            if(X[i-1]==Y[j-1])
                cause[i][j] = cause[i-1][j-1]+1;
            else
                cause[i][j] = max(cause[i-1][j],cause[i][j-1]);
        }
    }
    return cause[len1][len2];
}

猜你喜欢

转载自blog.csdn.net/m0_56603583/article/details/122473794