算法之最长公共子序列问题

一、问题描述

最长公共子序列(longest common sequence)。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。子序列每个元素的下标严格递增。


       如上图,给定的字符序列: {a,b,c,d,e,f,g,h},它的子序列示例: {a,c,e,f} 即元素b,d,g,h被去掉后,保持原有的元素序列所得到的结果就是子序列。同理,{a,h},{c,d,e}等都是它的子序列。

        最长公共子序列(以下都简称LCS)即给定序列s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2},s1和s2的相同子序列,且该子序列的长度最长,即是LCS。s1和s2的其中一个最长公共子序列是 {3,4,6,7,8}

二、问题分析

1.最优子结构:设有序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},它们的最长公共子序列是Z={z1,z2,…zk},则:

①若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列;

②若xm!=yn,且zk!=xm,则Z是Xm-1和Y的最长公共子序列;

③若xm!=yn,且zk!=yn,则Z是X和Yn-1的最长公共子序列;

扫描二维码关注公众号,回复: 1059693 查看本文章

其中Xm-1={x1,x2,…,xm-1},Yn-1={y1,y2,…,yn-1},Zk-1={z1,z2,…zk-1};

2.子问题的递归结构:c[i][j]记录序列Xi和Yj的最长公共子序列的长度;

 



#include <iostream>
using namespace std;
#define M 8
#define N 7

//序列x长度xl+1,序列y长度yl+1,
//c[i][j]记录子序列Xi和Yj的最长公共子序列长度,
//b[i][j]记录c[i][j]的值是由哪一个子问题得到的
void LCSLength(int xl,int yl,char x[],char y[],int c[M][N],int b[M][N])
{
    for(int i=0;i<xl;i++){c[i][0]=0;b[i][0]=0;} //多了一行和一排表示序列x和y都是空序列的情况
    for(int i=0;i<yl;i++){c[0][i]=0;b[0][i]=0;}
    for(int i=1;i<xl;i++)
    {
        for(int j=1;j<yl;j++)
        {
            if(x[i-1]==y[j-1])
            {
                c[i][j]=c[i-1][j-1]+1;
                b[i][j]=1;
            }
            else {
                c[i][j]=c[i-1][j];
                int t = c[i][j-1];
                if(c[i][j]<t)
                {
                    c[i][j]=t;
                    b[i][j]=2;
                }
                else b[i][j]=3;
            }
        }
    }
}

void LCS(int i,int j,char x[],int b[M][N])
{
    if(i==0||j==0)return;
    if(b[i][j]==1){
        LCS(i-1,j-1,x,b);
        cout<<x[i-1]<<" ";
    }
    else if(b[i][j]==2)LCS(i,j-1,x,b);
    else LCS(i-1,j,x,b);
}


int main()
{
    char x[]={'A','B','C','B','D','A','B'},
         y[]={'B','D','C','A','B','A'};
    int c[M][N],b[M][N];
    LCSLength(M,N,x,y,c,b);
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<N;j++)
            cout<<c[i][j]<<" ";
        cout<<endl;
    }
    LCS(M-1,N-1,x,b);
}

复杂性分析:O(n^2);

猜你喜欢

转载自blog.csdn.net/qq_35503380/article/details/80382815