题目:给定一个query和一个text,均由小写字母组成。要求在text中找出以同样的顺序连续出现在query中的最长连续字母序列的长度。例如, query为“acbac”,text为“acaccbabb”,那么text中的“cba”为最长的连续出现在query中的字母序列,因此,返回结果应该为其长度3。请注意程序效率。
解析:本题即求最长公共子字符串,用动态规划算法解决。
动态规划:
1. 令C[i][j]表示Xi 和Yi的最大substring长度,动态转移方程为: 如果Xi==Yi, 则C[i][j]=C[i-1][j-1]+1;
如果Xi==Yi,则C[i][j]=0;
2.求最长公共子字符串:Longest Common Substring=max{C[i][j], 1<=i<=n, 1<=j<=m}
具体代码:
#include<iostream>
#include<cstring>
using namespace std;
int longest_common_substring(char* s,char* t)
{
int i,j,len1,len2,m,x,y;
len1=strlen(s);
len2=strlen(t);
int **c;
c=new int*[len1+1];
for(i=0;i<len1+1;i++)
c[i]=new int[len2+1];
for(i=0;i<len1+1;i++)
c[i][0]=0;
for(j=0;j<len2+1;j++)
c[0][j]=0;
m=-1;
for(i=1;i<len1+1;i++)
{
for(j=1;j<len2+1;j++)
{
if(s[i-1]==t[j-1])
c[i][j]=c[i-1][j-1]+1;
else
c[i][j]=0;
if(c[i][j]>m)
{ m=c[i][j];
x=i;
y=j;
}
}
}
/*
for(i=0;i<len1+1;i++)
{
for(j=0;j<len2+1;j++)
{
cout<<c[i][j]<<" ";
}
cout<<endl;
}
*/
//输出公共子字符串
char output[100];
int k=m;
i=x-1;j=y-1;
output[k--]='\0';
while(i>=0&&j>=0)
{
if(s[i]==t[j])
{
output[k--]=s[i];
i--;
j--;
}
else
break;
}
// cout<<output<<endl; //输出最长字符串成
int len=strlen(output);
cout<<len<<endl;
for(i=0;i<len1+1;i++)
delete[] c[i];
delete[] c;
return m;
}
int main()
{
char text[100],query[100];
cin>>text;
cin>>query;
longest_common_substring(text,query);
return 0;
}