LCS 算法实现

动态规划算法

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;

#define MAXSTRLEN 20

int Lcs(char x[], char y[], int path[][MAXSTRLEN])//求序列x和y的最长公共子序列,path保存路径指向,以方便打印公共子序列
{
    int i, j;
    int len1=strlen(x)-1;
    int len2=strlen(y)-1;

    int **c=new int*[len1+1];
    for(i=0; i<=len1; i++)
        c[i]=new int[len2+1];

    for(i=0; i<=len1; i++)
        c[i][0]=0;
    for(i=0; i<=len2; i++)
        c[0][i]=0;
    for(i=1; i<=len1; i++)
        for(j=1; j<=len2; j++)//从x[1],y[1]开始
        {
            if(x[i]==y[j])
            {
                c[i][j]=c[i-1][j-1]+1;
                path[i][j]=1;
            }
            else if(c[i-1][j]>=c[i][j-1])
            {
                c[i][j]=c[i-1][j];
                path[i][j]=2;
            }
            else
            {
                c[i][j]=c[i][j-1];
                path[i][j]=3;
            }
        }

        return c[len1][len2];
}

void PrintLcs(int i, int j, char x[], int path[][MAXSTRLEN])//打印最长公共子序列
{
    if(i==0 || j==0)
        return;

    if(path[i][j]==1)
    {
        PrintLcs(i-1, j-1, x, path);
        cout<<x[i];
    }
    else if(path[i][j]==2)
        PrintLcs(i-1, j, x, path);
    else
        PrintLcs(i, j-1, x, path);

}
void main()
{
    char a[MAXSTRLEN];
    char b[MAXSTRLEN];
    int path[MAXSTRLEN][MAXSTRLEN];
    gets(a+1);//a[0]不算,从a[1]开始
    gets(b+1);//b[0]不算,从b[1]开始

    cout<<Lcs(a, b, path)<<endl;
    cout<<"最长公共子序列:";
    PrintLcs(strlen(a)-1, strlen(b)-1, a, path);
    cout<<endl;

}

递归算法

#include <iostream>
using namespace std;

#define MAXSTRLEN 20

//递归算法
int Lcs(char *str1, char *str2)
{
    if(*str1==‘\0‘ || *str2==‘\0‘)
        return 0;
    if(*str1==*str2)
        return Lcs(str1+1, str2+1)+1;
    else if(Lcs(str1+1, str2)>Lcs(str1, str2+1))
        return Lcs(str1+1, str2);
    else
        return Lcs(str1, str2+1);

}

void main()
{
    char a[MAXSTRLEN];
    char b[MAXSTRLEN];

    gets(a);
    gets(b);
    cout<<Lcs(a, b)<<endl;

}
时间: 2024-07-31 11:43:32

LCS 算法实现的相关文章

WOJ 1047 LCS problem (LCS 算法总结 )

http://acm.whu.edu.cn/land/problem/detail?problem_id=1047 Description Recently, Flymouse reads a book about Algorithm and Data Structure. The book reads: there are two types of LCS Problems. One is Longest Common Subsequence problem. By the way of Dy

LCS算法思想

LCS问题就是求两个字符串最长公共子串的问题.解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0.然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.下面是字符串21232523311324和字符串312123223445的匹配矩阵,前者为X方向的,后者为Y方向的.不难找到,红色部分是最长的匹配子串.通过查找位置我们得到最长的匹配子串为:212320 0 0 1 0 0 0 1 1 0 0 1 0 0 00 1 0 0 0 0 0 0 0

非动态规划实现LCS算法

LCS(最长公共子串 longest common subsequence)一般都会采用动态规划的算法来实现,算法的时间复杂度大概是O(x2),  另外需要一个x2的额外空间, 这个算法这里我不做说明,给个讲得不错的教程地址 LCS教程 这边博文里我将给出一个不采用动态规划的算法,并且时间复杂度和动态规划算法相同,还不会使用到额外的空间,空间复杂度为O(0). 思路: 假设存在两个字符串l和r, 并且strlen(l) <= strlen(r), 将l字符串想象成一辆车, 将r字符串想象成公路,

LCS算法

一.问题描述 如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串. 注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中.二.最长公共子序列的结构 最长公共子序列的结构有如下表示: 设序列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且z

求两个字符串最大子串的lcs算法

/************************************************************************* > File Name: lcs.c > Author: dingzhengsheng > Mail: [email protected] > Created Time: 2015年05月20日 星期三 16时07分50秒 > Version: v0.01 > Description: > History: ****

LCS 算法

f[i][j] 一定是 f[i-1][j] 和 F[i][j-1] 转移过来的. 如果 把 a 串  看成字符数组 s1[], b 串 看成 s2[] ; 则: 如果 s1[i]!=s2[j] 那么 从 f[i-1][j] 和 f[i][j-1] 取一个最大值 记录到 F[i] [j]. 代码如下: f[i][j]=max(f[i-1][j],f[i][j-1]); 如果 s1[i] == s2[j] 那么 f[i][j] 是由 F[i-1][j-1]+1 推来的: 用dp方程式可以推出,如图:

LCS算法改进

public static void Lcs_Length(String X,String Y,int c[][]) { X=" "+X; Y=" "+Y; for(int i=1;i<X.length();i++) { c[i][0]=0; } for(int j=0;j<Y.length();j++) { c[0][j]=0; } for(int i=1;i<X.length();i++) { for(int j=1;j<Y.length

LCS(最长公共子序列)动规算法正确性证明

今天在看代码源文件求diff的原理的时候看到了LCS算法.这个算法应该不陌生,动规的经典算法.具体算法做啥了我就不说了,不知道的可以直接看<算法导论>动态规划那一章.既然看到了就想回忆下,当想到算法正确性的时候,发现这个算法的正确性证明并不好做.于是想了一段时间,里面有几个细节很trick,容易陷进去.想了几轮,现在把证明贴出来,有异议的可以留言一起交流. 先把一些符号和约定说明下: 假设有两个数组,A和B.A[i]为A的第i个元素,A(i)为有A的第一个元素到第i个元素所组成的前缀.m(i,

最长递增子序列 O(NlogN)算法

https://www.felix021.com/blog/read.php?entryid=1587&page=3&part=1 感谢作者! 标题:最长递增子序列 O(NlogN)算法 出处:Blog of Felix021 时间:Wed, 13 May 2009 04:15:10 +0000 作者:felix021 地址:https://www.felix021.com/blog/read.php?1587  内容: 今天回顾WOJ1398,发现了这个当时没有理解透彻的算法. 看了好久