首先这是一个单字符串问题。子字符串R 在字符串L 中至少出现两次,则称R 是L 的重复子串。重复子串又分为可重叠重复子串和不可重叠重复子串,这里只是简单讨论最长可重叠的重复子串.首先,最直接的方法就是子串和子串间相互比较,这样查看所有的子串对,时间复杂度为O(n^2)。最快的方法是使用后缀数组,如果子串R在L中重复出现,则R至少是L的两个后缀数组的前缀,后缀数组最难的就是如何构建后缀数组,网上有很多博客讨论了相关的算法,这里只是简单的使用排序算法,为的只是理解思想:
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int commonLenght(const string& s1,const string& s2)
{
int length = min(s1.size(),s2.size()),i;
for(i = 0;i < length;++i)
{
if(s1[i] != s2[i])break;
}
return i;
}
string LRS(string s)
{
vector<string> suffix;
int i,maxLength = 0;
for(i = 0;i < s.size();++i)
{
suffix.push_back(s.substr(i));//取所有的后缀数组
}
sort(suffix.begin(),suffix.end());//对后缀数组进行排序
string res;
for(i = 0;i < suffix.size()-1;++i)
{
int len = commonLenght(suffix[i],suffix[i+1]);//比较相邻的两个后缀数组
if(len > maxLength)
{
maxLength = len;
res = suffix[i].substr(0,len);
}
}
return res;
}
int main()
{
string s;
while(cin >> s)
{
cout << LRS(s) << endl;
}
}