首先这是一个单字符串问题。子字符串R 在字符串L 中至少出现两次,则称R 是L 的重复子串。重复子串又分为可重叠重复子串和不可重叠重复子串。
方法:
KMP算法求解
在KMP算法的关键就是求解next数组,针对next[j]=k,可以得到P[0,1,...,k-1]=P[j-k,j-k+1,...,j-1]。看到P[0,1,...,k-1]=P[j-k,j-k+1,...,j-1]应该会眼前一亮,大脑顿时清醒些,这不就是重复子串吗!由此求解最长重复子串就转化为求解KMP算法next数组中的最大值(即max{next[j]=k}。
现在就是求解next数组的问题了
int getNext(char *str,int *next)
{
int len=strlen(str);
int index=0;
int k=-1;
next[0]=k;
int max=0;
//kmp算法求next值,取得最大的字串
while (index<len)
{
if (k==-1 || str[index]==str[k])
{
k++;
index++;
next[index]=k;
if (k>max)//求得其中重复最大的字串的个数,也就是与最前面串的重复数
{
max=k;
}
}
else
k=next[k];
}
return max;
}
int main()
{
char str[50];//输入字符串
cin>>str;
int max=0;//最大的字串
int nextMax;//接受getNext函数中返回的最大值
int index;
int maxIndex;//保存最大的字串起始位置
int len=strlen(str);
//将一个字符串从开始一直减少到只剩一个字符,通过这个取得最小字串
for (index=0;index<len-1;index++)
{
int *next=new int[len-index];//取得next在这没用
nextMax=getNext(str+index,next);//每次从str+index开始
if (nextMax>max)
{
max=nextMax;
maxIndex=index;
}
}
//输出最长字串
cout<<"最长字串: ";
for (index=0;index<max;index++)
{
cout<<str[index+maxIndex];
}
cout<<endl;
return 0;
}