求字符串中重复出现的最长字串
例如字符串:drgabcifrabcsdrrs中,最长公共字串是:abc
方法:利用后缀树来求。
字符串的后缀树有如下:
drgabcifrabcsdrrs
rgabcifrabcsdrrs
gabcifrabcsdrrs
abcifrabcsdrrs---------s1
..............
rabcsdrrs
abcsdrrs-----------s2
...............
我们求的这些后缀字符串中,某2个串的最长公共前缀就是想要的答案。比如s1和s2的最长公共前缀:abc
我们为了简化运算,讲后缀字符串排序,这样前缀相同的就会排在相邻的位置上。
代码如下:
#include<iostream>
#include<string>
using namespace std;
int commonStr(string str1,string str2)//求两个字符串最长公共前缀长度
{
int len = (str1.length()>str2.length())?str2.length():str1.length();
int i=0;
while(i<len && str1[i]==str2[i])
i++;
return i;
}
void maxLen(string str,string &key)//求字符串str的最长重复字串,key是用来存放前缀的
{
int len = str.length();
string *sub= new string[len];//定义一个字符串数据存放后缀字符串
for(int i=0;i<len;i++)
{
sub[i] = str.substr(i,len-i);
}
sort(sub,sub+len);//对后缀字符串进行排序
int max = 1;
for(int i = 1;i<len;i++)
{
int count = commonStr(sub[i],sub[i-1]);//计算相邻的字符串的公共前缀长度
if(max<count)//如果当前长度大于最大长度,那么更新max和key
{
key = sub[i].substr(0,count);
max = count;
}
}
}
int main()
{
string str = "yyabcdabjcabcdg";
string key = "abc";
maxLen(str,key);
cout<<key<<endl;
getchar();
return 0;
}