⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poj2774_a后缀数组_最长公共子串.cpp

📁 本人最近在acm.pku.edu.cn上通过的程序
💻 CPP
字号:
//后缀数组求两字符串最长公共子串
//利用sort 实现简单 效率略低
#include <algorithm>
using namespace std;

const int MAXLEN =  200100;
int n;
int power, lstSA[MAXLEN], lstRank[MAXLEN], SA [MAXLEN], rank[MAXLEN], h[MAXLEN], height[MAXLEN];
char ts[MAXLEN], str[MAXLEN];

bool cmpChar(const int &a, const int &b){
    return str[a] < str[b];
}

bool cmpLst(const int& a, const int& b){
  	return lstRank[a]<lstRank[b]||lstRank[a]==lstRank[b]&&lstRank[a+power]<lstRank[b+power];
}

void suffixArray(){
  	for (int i = 0; i<n; i++) SA[i] = i;
  	sort(SA, SA+n, cmpChar);
  	for (int i = 0, j = 0; i<n; i++) {
    	if (i>0&&str[SA[i]]!=str[SA[i-1]]) j++;
    	rank[SA[i]] = j;
  	}
  	for (power = 1; rank[SA[n-1]]<n-1; power *= 2) {
    	memcpy(lstRank, rank, sizeof(int)*n);
    	memcpy(lstSA, SA, sizeof(int)*n);
    	sort(SA, SA+n, cmpLst);
    	for (int i = 0, j = 0; i<n; i++) {
      		if (i>0&&cmpLst(SA[i-1], SA[i])) j++;
      		rank[SA[i]] = j;
    	}
  	}
}

void getheight(){
	int i, j, h; 
	height[0] = 0;
	for (i = 0; i < n; i++) rank[SA[i]] = i;
	for (h = 0, i = 0; i < n; i++) 
		if (rank[i] > 0){
			j = SA[rank[i]-1];
			while (str[i+h] == str[j+h]) ++h;
			height[rank[i]] = h;
			if (h > 0) --h;	
		}	
}


void solve(){
	gets(str);
	int l1 = strlen(str);
	str[l1] = '$';
	gets(str + l1 + 1);
	n = strlen(str);
	suffixArray(); getheight();
	int ans = 0;
	for (int i = 1; i < n; i++){
		if (height[i] >= ans && SA[i - 1] < l1 && SA[i] > l1)
			ans = height[i];
		if (height[i] >= ans && SA[i] < l1 && SA[i - 1] > l1)
			ans = height[i];
	}
	printf("%d\n", ans);
}

int main(){
	freopen("test.in", "r", stdin);
	freopen("test.out", "w", stdout);
	solve();
	return 0;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -