1. 程式人生 > >最長重複子串(可重疊)

最長重複子串(可重疊)

首先這是一個單字串問題。子字串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;
	}
}