最长公共子串(Longest Common Substring): 是指两个字符串中最长连续相同的子串长度。
例如:x[ ]=“ABCADBB”,y[ ]=”BCEDBB”,则x,y的最长公共子串为DBB。
因为此问题存在最优子结构的形式,所以我们采用动态规划的方法来求解。
用C[i][j]表示x[1...i],y[1...j]中,以x[i],y[j]结尾的最长公共子串z[1...l]的长度。
则最长公共子串的长度 pmax= max{ C[i][j] } (1<=i<=n , 1<=j<=m)
首先建立递推关系式:
然后利用递推关系进行计算
首先对 C[i][j] 进行初始化,C[i][0] = C[0][j] =0;
用pmax表示最长公共子串的末位位置,lmax表示最长公共子串的长度
则最长公共子串为<x[pmax-lmax+1],x[pmax-lmax+2],...,x[pmax]>
算法实例
代码
#include<iostream>
using namespace std;
int lmax=0,pmax=0;
void Longest_Common_Substring(char X[],char Y[],int C[][20],int n,int m)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(X[i]==Y[j])
{
C[i][j]=C[i-1][j-1]+1;
if(C[i][j]>lmax)
{
lmax=C[i][j];
pmax=i;
}
}
else
{
C[i][j]=0;
}
}
}
}
int main()
{
int n,m;
cout<<"请输入字符串X和Y的长度:"; //7 6
cin>>n>>m;
char X[n+1],Y[m+1];
cout<<"请输入字符串X:"; //ABCADBB
for(int i=1;i<=n;i++)
cin>>X[i];
cout<<"请输入字符串Y:"; //BCEDBB
for(int i=1;i<=m;i++)
cin>>Y[i];
int C[20][20]; //求解
char Rec[20][20]; //记录位置
//初始化
for(int i=0;i<=n;i++)
C[i][0]=0;
for(int i=0;i<=m;i++)
C[0][i]=0;
Longest_Common_Substring(X,Y,C,n,m);
cout<<"最长公共子序列长度为:"<<lmax<<endl;
cout<<"最长子串为:";
for(int i=pmax-lmax+1;i<=pmax;i++)
cout<<X[i];
}
运行结果