///串S1长度m,S2长度n,m<=n,求最大公共子串
///如S1='abcd' 可分解为'abcd','abc','bcd','ab','bc','cd','a','b','c','d'
///同一长度K的子串个数m-k+1
///Author: Acefly
#include <stdio.h>
#include <iostream.h>
/// <summary>
///得到最大公共子串长度及在S1,S2中的位置
///</summary>
int getMaxSub(string S1,string S2,int *P1,int *P2,int lenS1,int lenS2)
{
///以*P1,*P2记下子串在S1,S2种的起始位置
int i,j,K;
string x;//用于交换S1,S2
//使S1的长度总小于S2的长度,K值保存S1的长度
if(lenS1>lenS2)
{
K=lenS2;
x=S1;
S1=S2;
S2=x;
}
else
{
K=S1.length();
}
while(K>0)
{
//S1由大至小分解成若干子串的个数,最外层循环
for(*P1=0;*P1<lenS1-K+1;(*P1)++)
{
i=*P1;*P2=0;j=*P2;
while(i<(*P1)+K&&j<lenS2)
{
if(S1[i]==S2[j])
{
i++;j++;
}
else
{
(*P2)++;
j=*P2;
i=*P1;
}
}
if(i==(*P1)+K)
return(K);
}
K--;
}
*P1=-1;
*P2=-1;//不存在公共子串
return(0);
}
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
int wait;
int A1;
int A2;
int subLength;
string str1,str2;
cout <<"取S1,S2中最大公共串"<<endl;
cout << "请输入S1:"<<endl;
cin >> str1;
cout << "请输入S2:"<<endl;
cin >> str2;
cout << endl;
int lenS1 = str1.length(); //存储字符串S1长度
int lenS2=str2.length(); //存储字符串S2长度
subLength=getMaxSub(str1,str2,&A1,&A2,lenS1,lenS2);
//输出公共字符串
if(subLength!=0)
{
cout << "最大公共子串为:" ;
if(lenS1<lenS2)
{
for(int i=A1;i<A1+subLength;i++)
{
cout << str1[i];
}
}
else
{
for(int i=A1;i<A1+subLength;i++)
{
cout << str2[i];
}
}
cout << endl;
}
else
{
cout << "不存在公共子串!";
}
cin >> wait; //观察结果
}
//---------------------------------------------------------------------------