一、知识概述

1.1 最长公共子序列

 1. 若给定序列X={ x 1 x_1 x1 x 2 x_2 x2,…, x m x_m xm},则另一序列Z={ z 1 z_1 z1 z 2 z_2 z2,…, z k z_k zk}是X的子序列,是指存在一个严格递增下标序列 { i 1 i_1 i1 i 2 i_2 i2,…, i k i_k ik},使得对于所有 j=1,2,…,k,有: z j z_j zj = x i j x_{ij} xij 。如:序列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的公共子序列。若序列Z有最长的长度,则称Z是序列X和Y的最长公共子序列。

 3. 最长公共子序列问题:给定两个序列X={ x 1 x_1 x1 x 2 x_2 x2,…, x m x_m xm}和Y={ y 1 y_1 y1 y 2 y_2 y2,…, y n y_n yn},找出X和Y的最长公共子序列。

1.2 进行动态规划

 1. 最长公共子序列问题具有最优子结构性质。设序列X={ x 1 x_1 x1 x 2 x_2 x2,…, x m x_m xm}和Y={ y 1 y_1 y1 y 2 y_2 y2,…, y n y_n yn}的最长公共子序列为Z={ z 1 z_1 z1 z 2 z_2 z2,…, z k z_k zk},则:

在这里插入图片描述
 2. 用c[i][j]记录序列的最长公共子序列的长度。二维表b是辅助构造最优解的信息表。

在这里插入图片描述
在这里插入图片描述

二、例题分析

2.1 例题1

在这里插入图片描述

2.2 例题2

在这里插入图片描述

三、代码

3.1 完整代码

#include<bits/stdc++.h>
using namespace std;
const int Size = 1010;   //尽量用全局变量
int c[Size][Size];
int b[Size][Size];    
int LCS_length(string X, string Y)
{
    int m = X.size();
    int n = Y.size();
    for(int i=1; i<=m; i++)
	{
		c[i][0] = 0;
	} 
	for(int j=1; j<=n; j++)
	{
		c[0][j] = 0;
	} 
    for(int i=1; i<=m; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(X[i-1] == Y[j-1]) 
            {
                c[i][j] = c[i-1][j-1] + 1;
                b[i][j] = 1;
            }
            else if(c[i-1][j] >= c[i][j-1])
            {
                c[i][j] = c[i-1][j];
                b[i][j] = 2;
            }
            else
            {
                c[i][j] = c[i][j-1];
                b[i][j] = 3;
            }
        }
    }
    return c[m][n]; //最长公共子序列的长度 
}
void LCS(string X, int i, int j)
{
    if(i==0 || j==0) return;
    if(b[i][j] == 1) 
    {
        LCS(X, i-1, j-1);
        cout<<X[i-1];  //a[i-1]==b[j-1]
    }
    else if(b[i][j]==2) LCS(X, i-1, j);
    else if(b[i][j]==3) LCS(X, i, j-1);
}
int main()
{
    string X, Y;
    
    cout<<"请输入两个字符串:"<<endl;
    cin>>X>>Y;
    cout<<"最大公共子序列长度为:"<<LCS_length(X, Y)<<endl;
    cout<<"最大公共子序列为:";
    LCS(X, X.size(), Y.size());
    
    return 0;
}

在这里插入图片描述

3.2 代码探讨

 问题:如果c[i-1][j] = c[i][j-1],b[i][j]=2 or 3?不同的选择对结果有影响吗?

 答:不影响最长公共子序列的长度,但是可能会产生不一样的最长公共子序列。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐