最长公共子串长度

来源:互联网 发布:域名注册管理局 编辑:程序博客网 时间:2024/06/06 01:28

问题描述

我们称序列Z = < z1, z2, ..., zk >是序列X = < x1, x2, ..., xm >的子序列当且仅当存在严格上升的序列< i1, i2, ..., ik >,使得对j = 1, 2, ... ,k, 有xij = zj。比如Z = < a, b, f, c > 是X = < a, b, c, f, b, c >的子序列。

现在给出两个序列X和Y,你的任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列。

输入数据

输入包括多组测试数据。每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列。两个字符串之间由若干个空格隔开。

输出要求

对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度。

 

 

解题思路

如果我们用字符数组s1、s2存放两个字符串,用s1[i]表示s1中的第i个字符,s2[j]表示s2中的第j个字符(字符编号从1开始,不存在“第0个字符”),用s1i表示s1的前i个字符所构成的子串, s2j表示s2的前j个字符构成的子串,MaxLen(i, j)表示s1i 和s2j的最长公共子序列的长度,那么递推关系如下:

if( i ==0 || j == 0 ) {

MaxLen(i, j) = 0 //两个空串的最长公共子序列长度当然是0

}

else if( s1[i] == s2[j] )

MaxLen(i, j) = MaxLen(i-1, j-1 ) + 1;

else {

MaxLen(i, j) = Max( MaxLen(i, j-1), MaxLen(i-1, j));

}

// File Name: zuichanggongongzixulielen.cpp// Author: rudolf// Created Time: 2013年04月24日 星期三 15时00分46秒#include<vector>#include<list>#include<map>#include<set>#include<deque>#include<stack>#include<bitset>#include<algorithm>#include<functional>#include<numeric>#include<utility>#include<sstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cmath>#include<cstdlib>#include<cstring>#include<ctime>#define  MaxSize 200#include <stdio.h>#include <string.h>using namespace std;char p[MaxSize+10];char q[MaxSize+10];int MaxComLen[MaxSize+10][MaxSize+10];  //MaxComLen[i][j]表示以第一个串第i个元素,第二个串第j个元素为终点的最大公共子串int main(){int i,j,max;int plen=0,qlen=0;while(scanf("%s%s",p+1,q+1)>0){int maxlen=0;plen=strlen(p+1);qlen=strlen(q+1);for (i=0;i<=plen;i++)MaxComLen[i][0]=0;for (j=0;j<=qlen;j++)MaxComLen[0][j]=0;           //如果i或者j为0,最长公共字串为0for(i=1;i<=plen;i++){for (j=1;j<=qlen;j++){if (p[i]==q[j])MaxComLen[i][j]=MaxComLen[i-1][j-1]+1;else{if(MaxComLen[i-1][j]>MaxComLen[i][j-1])MaxComLen[i][j]=MaxComLen[i-1][j];elseMaxComLen[i][j]=MaxComLen[i][j-1];}if (MaxComLen[i][j]>maxlen)          //输出最大的长度,按照定义应该为最后一个元素maxlen=MaxComLen[i][j];}}printf("%d\n",maxlen);}return 0;}





int findresult(int pa,int pb)    {        if(dp[pa][pb]>=0)            return dp[pa][pb];        if(pa==0)        {            int i;int flag=0;            for(i=0;i<=pb;i++)                if(wordA[pa]==wordB[i])                {                    dp[pa][i]=1;                    flag=1;                }            return flag;        }        if(pb==0)        {            int i;int flag=0;            for(i=0;i<=pa;i++)                if(wordA[i]==wordB[pb])                {                    dp[i][pb]=1;                    flag=1;                }            return flag;        }        int tmp=MIN;        if(wordA[pa]==wordB[pb])            tmp=findresult(pa-1,pb-1)+1;        tmp=maxnum(tmp,findresult(pa-1,pb));         tmp=maxnum(tmp,findresult(pa,pb-1));        dp[pa][pb]=tmp;        return tmp;    }


原创粉丝点击