您的位置:首页 > 其它

最长重复字串和两字符串中最长公子子串问题

2011-05-30 16:52 260 查看
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;
}


通过将一个字符串分成n-1个子串,每次通过kmp算法取得字串的next值,从而算出该子串的最长重复子串,保存最大的,就可得答案

其中getNext函数只能取得的是这个子串中后面的子串与开始子串的重复数,所以通过这个思路将一个长的字符串分解为n-1个子串即可

2、两字符串中的最长公共子串

void getMaxStr(char *str1,char *str2)
{
int len1=strlen(str1);
int len2=strlen(str2);
int *next=new int[len2];
int max=0;
int maxIndex=0;

//将较短的串分开,分成n串,每次进行kmp比较
for (int indexStr2=0;indexStr2<len2;indexStr2++)
{
//取得每次的next的值
getNext(str2+indexStr2,next);
int k=0;
int index=0;
while (index<len1 && k<len2-indexStr2)
{
//kmp比较,取得最大的比较字串的长度和str2的开始位置,不一定能完全匹配
if (k==-1 || *(str2+indexStr2+k)==*(str1+index))
{
k++;
index++;
if (k>max)
{
max=k;
maxIndex=indexStr2;
}
}
else
k=next[k];
}
}

//输出最长的公共子串
cout<<"最长字串: ";
for (int index=0;index<max;index++)
{
cout<<str2[index+maxIndex];
}
cout<<endl;
}


两个字符串中取得较短的字符串,与较长的字符串进行kmp比较,较短的字符串分成n个子串,因为kmp比较是从第一个字符开始比较的。

然后取得每次的最大的比较子段,记下str2的开始位置和长度。最后输出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: