两个字符串的最长公共子串-后缀数组

求解两个子串的最长公共子串一般常用的是动态规划算法,但是用后缀数组来处理这一类问题会非常简便,在很多刷题系统中基本都有最长公共子串的处理,所以这一类问题是比较重要的。

c++版本的后缀数组处理最长公共子串问题。

#include 
#include 
using namespace std;
#define MAX 1000
int ranked[MAX]={};
int sa[MAX] ={};
int height[MAX] = {};
int main(){
	string iQueryMaxCommString(string& str1, string& str2);
	string stringA;
	string stringB;
	cin >> stringA;
	cin >> stringB;
	cout << iQueryMaxCommString(stringA,stringB)<< endl;
	return 0;
}
void sbubble(string* str,int len){
	for (int i = 0;i < len - 1;i++)
		for (int j = 0; j < len - i - 1;j++)
			if (str[j] > str[j+1]){
				string temp = str[j];
				str[j] = str[j+1];
				str[j+1] = temp;
			}
}
int comstr(const string& a,const string& b){
	int count = 0;
	int len1 = a.length();       
	int len2 = b.length();
	for (int i = 0,j = 0;i < len1&&j < len2;i++,j++)
		if (a[i] == b[j])
			count++;
		else break;
	return count;
}
void claheight(string* str,int n){
	for (int i = 0,j = 1;i < n-1&&j < n;j++,i++)
		height[i] = comstr(str[i],str[j]);
}
 string iQueryMaxCommString(string& str1, string& str2){
	 int lenstr2 = str2.length();
	 int lenstr1 = str1.length();
	string str=str1;
	str = str+'$';
	str = str + str2;
	int len = str.length();
	string* backstr = new string[len];
	for (int i = 0; i < len;i++)
		for (int j = i; j < len;j++)
			backstr[i]+=str[j];
	sbubble(backstr,len);
	for (int i = 0; i < len;i++){
		int size = backstr[i].length();
		ranked[len - size] = i;
		sa[i] = len - size;
	}
	claheight(backstr,len);
	int max = height[0],pos;
	for (int i = 0,j = 1;i < len-1&&j < len;i++,j++)
		if ((backstr[i].length()>lenstr2+1&&backstr[j].length() <= lenstr2)||
			(backstr[j].length()>lenstr2+1&&backstr[i].length() <= lenstr2))
			if (max < height[i]){
				max = height[i];
				pos = i;
			}	
	for (int i = 0; i < len;i++)
		if (max == height[i]){
			pos = i;
			break;
		}
	string obstr;
	for (int i = 0; i < max;i++)
		obstr+=backstr[pos][i];
	delete[] backstr;	
		return obstr;
}


你可能感兴趣的:(算法设计和数据结构)