后缀数组

简介: #include #include #include #include #include #include using namespace std; string x; int sa[1111]=.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map> 
#include<string>
using namespace std;
string x;
int sa[1111]={0}, ch[33] = {0};
int d[2777][2777] = {0}, last = 0;
struct data{
	int first, second, i;
	friend bool operator <(data a, data b){
		if (a.first != b.first) return a.first < b.first;
		return a.second < b.second;
		
	}
}q[1111];
int main(){
	cin>>x;
	int n = x.length();
	for (int i = 0; i < n-1; i++){
		q[i].first= x[i];
		q[i].second = x[i+1];
		q[i].i = i;
	}	q[n-1].first= x[n-1]; q[n-1].second = 0; q[n-1].i = n-1;
	for (int k = 2; k <= n; k <<= 1){
		sort(q, q + n);
	    int cnt  = 0;
		for (int i = 0; i < n; i++){
			if (i && q[i].first == q[i-1].first && q[i].second == q[i-1].second )
				sa[q[i].i] = sa[q[i-1].i];
			else sa[q[i].i] = ++cnt;
		}
		for (int i = 0; i < n; i++) cout<<sa[i]<<' ';
		cout<<endl;    
		if (cnt >= n || k * 2 > n) break;
		for (int i = 0; i < n-k; i++) {
			q[i].first = sa[i];
			q[i].second = sa[i + k];
			q[i].i = i;
		}
		for (int i = n-k; i < n; i++){
			q[i].first = sa[i];
			q[i].second = 0;
			q[i].i  = i;
		}
	}    
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<string>
using namespace std;
char x[100111];
int sa[100111]={0};
int rank[100111];
struct data{
int first, second, i;
friend bool operator <(data a, data b){
if (a.first != b.first) return a.first < b.first;
return a.second < b.second;

}
}q[1111];
int n;
int find(char *p){
int m = strlen(p);
if (strncmp(p, x + sa[0], m) < 0 || strncmp(p, x + sa[n-1], m) > 0) return -1;
int L = 0, R = n-1;
while (R >= L){
int M = L + (R - L) / 2;
int res = strncmp(p, x + sa[M], m);
if (res == 0) return M;
if (res < 0) R = M - 1; else L = M + 1;
}
return -1;
}
int height[100111];
void GetHeight(){
int k = 0, i, j;
for (i = 1; i < n; i++){
if (k) k--;
int j = sa[rank[i] - 1];
while (x[i+k] == x[j+k]) k++;
height[rank[i]] = k;
}
for (int i = 1; i < n; i++) cout<<height[i]<<' ';
}
int main(){
ios::sync_with_stdio(false);
cin>>x;
n = strlen(x);
for (int i = 0; i < n-1; i++){
q[i].first= x[i];
q[i].second = x[i+1];
q[i].i = i;
} q[n-1].first= x[n-1]; q[n-1].second = 0; q[n-1].i = n-1;
for (int k = 2; k <= n; k <<= 1){
sort(q, q + n);
int cnt = -1;
for (int i = 0; i < n; i++){
if (i && q[i].first == q[i-1].first && q[i].second == q[i-1].second )
rank[q[i].i] = rank[q[i-1].i];
else rank[q[i].i] = ++cnt;
}
// for (int i = 0; i < n; i++) cout<<rank[i]<<' ';
// cout<<endl;
if (cnt >= n || k * 2 > n) break;
for (int i = 0; i < n-k; i++) {
q[i].first = rank[i];
q[i].second = rank[i + k];
q[i].i = i;
}
for (int i = n-k; i < n; i++){
q[i].first = rank[i];
q[i].second = 0;
q[i].i = i;
}
}
for (int i = 0; i < n; i++) sa[rank[i]] = i;
for (int i = 0; i < n; i++) cout<<sa[i]<<' ';
cout<<'\n';
GetHeight();
return 0;
}

相关文章
|
15天前
|
机器学习/深度学习 算法 测试技术
【字符串】【分类讨论】【KMP】1163. 按字典序排在最后的子串
【字符串】【分类讨论】【KMP】1163. 按字典序排在最后的子串
|
1月前
|
索引
《华为机试》——查找两个字符串a,b中的最长公共子串
《华为机试》——查找两个字符串a,b中的最长公共子串
|
3月前
|
C++
最长公共前缀(C++)
最长公共前缀(C++)
12 0
|
10月前
|
机器学习/深度学习
leetcode:14.最长公共前缀
要注意题目是要找公共前缀,不是子串,前缀的意思就是说前面必须是一样的。首先可以假设下标为0的元素就是目前找到的最长公共前缀,然后从下标1开始遍历,看看当前元素与第0个元素的公共前缀是什么,比较他们的长度,取较短的就是这次循环结束后的公共前缀了。
43 0
|
测试技术
每日一题——倒置字符串
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
|
算法 测试技术
leetcode-13-最长公共前缀
算法题 leetcode-13-最长公共前缀
|
机器学习/深度学习 存储 容器
1044. 最长重复子串 :「字符串哈希 + 二分」&「后缀数组」
1044. 最长重复子串 :「字符串哈希 + 二分」&「后缀数组」
|
算法
LeetCode-14. 最长公共前缀(day4)
LeetCode-14. 最长公共前缀(day4)
122 0
|
算法
leetcode算法14.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 “”。
96 0
leetcode算法14.最长公共前缀