码迷,mamicode.com
首页 > 其他好文 > 详细

最长公共子序列LCS

时间:2015-08-07 21:47:30      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:

定义:

   子序列:原序列的一部分,要求按原序列中的顺序出现,但不要求连续

问题描述:

    给定两个序列X=<x1,x2,...,xm>和Y=<y1,y2,...,yn>,找出X和Y的最大长度公共子序列

求解:

步骤一:最优子结构(描述一个最长公共子序列LCS)

        定义:Xi=<x1,x2,...,xi>,Yi=<y1,y2,...,yi>

       假设Z=<z1,z2,...,zk>为X和Y的一个LCS,则有:

      1)如果xm=yn,那么zk=xm=yn,而且Zk-1是Xm-1和Yn-1的一个LCS

      2)如果xm!=yn,那么如果zk!=xm,则Z是Xm-1和Yn的一个LCS

                                     如果zk!=yn,则Z是X和Yn-1的一个LCS

步骤二:构造递归解

     定义:

           c[i,j]为序列Xi和Yi的一个LCS的长度

     公式:

            c[i,j]=0                               if i=0 or j =0  

            c[i,j]=c[i-1,j-1]+1                if i,j>0 and xi=yj

            c[i,j]=max(c[i-1,j],c[i,j-1])    if i,j>0 and xi!=yj

步骤三:明确重叠的子问题以及真正子问题的数目

           计算c[i-1,j]和c[i,j-1]都会计算c[i-1,j-1]

           由递归解的形式可以直接看出,子问题的数目是Θ(mn)

步骤四:算法设计

代码如下:

int calCLS(string s1,string s2)
{
    string::size_type m=s1.size()+1;
    string::size_type n=s2.size()+1;
    int i,j;
    int **c=new int*[m];
    for(i=0;i<m;i++)
        c[i]=new int[n];
    for(i=1;i<m;i++)
        c[i][0]=0;
    for(j=0;j<n;j++)
        c[0][j]=0;
    for(i=1;i<m;i++)
    {
        for(j=1;j<n;j++)
            if(s1[i]==s2[j])
                c[i][j]=c[i-1][j-1]+1;
            else
                if(c[i-1][j]>=c[i][j-1])
                    c[i][j]=c[i-1][j];
                else
                    c[i][j]=c[i][j-1];
    }
    return c[m-1][n-1];
}

 

          

 

最长公共子序列LCS

标签:

原文地址:http://www.cnblogs.com/xiangzhi/p/4711781.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!