後綴數組

char s[maxn];//構造字符串s的後綴數組,複雜度爲o(nlogn)
int sa[maxn],t[maxn],t2[maxn],c[maxn],n;
//每個字符的值必須爲0~m-1
void build_sa(int m){
	int i,*x = t,*y = t2,n = strlen(s);
	for(i = 0;i < m;i++)c[i] = 0;
	for(i = 0;i < n;i++)c[x[i] = s[i]]++;
	for(i = 1;i < m;i++)c[i] += c[i - 1];
	for(i = n - 1;i >= 0;i--)sa[--c[x[i]]] = i;
	for(int k = 1;k <= n;k <<= 1){
		int p = 0;
		for(i = n - k;i < n;i++)y[p++] = i;
		for(i = 0;i < n;i++)if(sa[i] >= k)y[p++] = sa[i] - k;
		for(i = 0;i < m;i++)c[i] = 0;
		for(i = 0;i < n;i++)c[x[y[i]]]++;
		for(i = 0;i < m;i++)c[i] += c[i - 1];
		for(i = n - 1;i >= 0;i--)sa[--c[x[y[i]]]] = y[i];
		swap(x,y);
		p = 1;x[sa[0]] = 0;
		for(i = 1;i < n;i++)
			x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
		if(p >= n)break;
		m = p;
	}
}
/*
單個模板串在原文本中找它存在的位置的複雜度爲mlog(n),m爲模板串長度,n爲文本長度
int m;
int cmp_suffix(char * pattern,int p){
	return strncmp(pattern,s + sa[p],m);
}

int find(char * pp){
	m = strlen(pp);
	if(cmp_suffix(pp,0) < 0)return -1;
	if(cmp_suffix(pp,n - 1) > 0)return -1;
	int L = 0,R = n - 1;
	while(R >= L){
		int M = (L + R) >> 1;
		int res = cmp_suffix(pp,M);
		if(!res)return M;
		if(res < 0)R = M - 1;else L = M + 1;
	}
	return -1;
}
*/
//其中rank[i]爲後綴i在sa數組中的下標,height[i]爲sa[i - 1]和sa[i]的最長公共前綴
int rank[maxn],height[maxn];
void getHeight(){//複雜度爲o(n)
	int i,j,k = 0;
	for(int i = 0;i < n;i++)rank[sa[i]] = i;
	for(int i = 0;i < n;i++){
		if(k)k--;
		int j = sa[rank[i] - 1];
		while(s[i + k] == s[j + k])k++;
		height[rank[i]] = k;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章