博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SA后缀数组
阅读量:6381 次
发布时间:2019-06-23

本文共 3054 字,大约阅读时间需要 10 分钟。

需要再多去理解

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #define inf (0x7fffffff) 10 #define l(a) ((a)<<1) 11 #define r(a) ((a)<<1|1) 12 #define b(a) (1<<(a)) 13 #define rep(i,a,b) ;for(int i=a;i<=(b);i++) 14 #define clr(a) memset(a,0,sizeof(a)) 15 typedef long long ll; 16 typedef unsigned long long ull; 17 using namespace std; 18 int readint(){ 19 int t=0,f=1;char c=getchar(); 20 while(!isdigit(c)){ 21 if(c=='-') f=-1; 22 c=getchar(); 23 } 24 while(isdigit(c)){ 25 t=(t<<3)+(t<<1)+c-'0'; 26 c=getchar(); 27 } 28 return t*f; 29 } 30 const int maxn=2000009; 31 int n,m=256,mn=maxn,sa1[maxn],a[maxn],sum[maxn],sa[maxn],rank[maxn],height[maxn];//sa与rank意义相反 32 char s[maxn]; 33 void cal_SA(){ 34 clr(sum); 35 rep(i,1,n) sum[rank[i]=s[i]]++;//求初始rank 36 rep(i,1,m) sum[i]+=sum[i-1]; 37 for(int i=n;i;i--) sa[sum[rank[i]]--]=i;///基数排序求初始sa 注意这个奇妙的操作! 38 for(int l=1;l
<<=1){ 39 //printf("rank==");rep(i,1,n) printf("%d ",rank[i]);puts(""); 40 //printf("sa==");rep(i,1,n) printf("%d ",sa[i]);puts(""); 41 42 int cnt=0; 43 rep(i,n-l+1,n) sa1[++cnt]=i;//后面的第二关键字为最小 44 rep(i,1,n) if(sa[i]>l) sa1[++cnt]=sa[i]-l;//利用sa对第二关键字的排序(sa1即第二关键字的sa) 45 46 //printf("sa1==");rep(i,1,n) printf("%d ",sa1[i]);puts(""); 47 48 rep(i,1,n) a[i]=rank[sa1[i]];//a为按第二关键字排序后的rank 注意! 49 50 //printf("a==");rep(i,1,n) printf("%d ",a[i]);puts(""); 51 52 clr(sum);rep(i,1,n) sum[a[i]]++; 53 rep(i,1,n) sum[i]+=sum[i-1]; 54 for(int i=n;i;i--) sa[sum[a[i]]--]=sa1[i];//求出新的sa 55 //综合第一关键字对a排序 和上面类似的奇妙操作(a按第二关键字排序了,所以这样倒着统计即可) 56 57 //printf("sa==");rep(i,1,n) printf("%d ",sa[i]);puts(""); 58 59 cnt=0; 60 rep(i,1,n) a[i]=rank[i];//将rank的值保存出来 61 rep(i,1,n){ 62 rank[sa[i]]=(a[sa[i-1]]==a[sa[i]]&&a[sa[i-1]+l]==a[sa[i]+l])?cnt:++cnt; 63 }//计算出新的rank 此处要利用rank考虑字符串相同的情况 64 65 //printf("rank==");rep(i,1,n) printf("%d ",rank[i]);puts(""); 66 //puts(""); 67 68 if(cnt==n) break;//cnt==n即排序完成 69 } 70 /*rep(i,1,n){ 71 printf("%d",rank[i]); 72 putchar(i==n?'\n':' '); 73 }*/ 74 rep(i,1,n){ 75 printf("%d",sa[i]); 76 putchar(i==n?'\n':' '); 77 } 78 } 79 void cal_Height(){ //height[i]=suffix(sa[i-1])和suffix(sa[i])的最大公共前缀 80 //suffix(i)和suffix(j)的最大公共前缀为min(height[rank[i]+1],height[rank[i]+2]...height[rank[j]]) 81 int k=0; 82 rep(i,1,n){ 83 if(k) k--; 84 int j=sa[rank[i]-1]; 85 while(s[i+k]==s[j+k]) k++; 86 height[rank[i]]=k; 87 }//利用h数组(h[i]=height[rank[i]])的性质(h[i]>=h[i-1]-1)(可证)计算height 88 rep(i,2,n){ 89 printf("%d",height[i]); 90 putchar(i==n?'\n':' '); 91 } 92 } 93 void init(){ 94 scanf("%s",s+1);n=strlen(s+1); 95 rep(i,1,n) sum[int(s[i])]=1; 96 rep(i,1,m) sum[i]+=sum[i-1]; 97 rep(i,1,n) s[i]=sum[s[i]-1]+1;//将字符串转变为从1开始的整数 98 } 99 int main(){100 //freopen("#input.txt","r",stdin);101 //freopen("#output.txt","w",stdout);102 init();103 cal_SA();104 cal_Height();105 //fclose(stdin);106 //fclose(stdout);107 return 0;108 }
View Code

 

转载于:https://www.cnblogs.com/chensiang/p/7868485.html

你可能感兴趣的文章
[Python3网络爬虫开发实战] 4-解析库的使用
查看>>
BCS--设置BDC元数据存储权限--访问被业务数据拒绝
查看>>
骑士 字符串的相关操作与内置函数(集合)
查看>>
SEO 百度后台主动推送链接
查看>>
File 类 操作实例
查看>>
CSS中浮动的使用
查看>>
Bad Habbits
查看>>
转:不应该不知道C++的常用库
查看>>
LeetCode:Pascal's Triangle I II
查看>>
vscode plugins
查看>>
数据结构排序
查看>>
vi技巧: 宏的使用技巧(其中怎样保存宏)那部分比较重要
查看>>
angular2.0学习笔记1.开发环境搭建 (node.js和npm的安装)
查看>>
.bashrc和.bash_profile的区别
查看>>
让你的PHP程序真正的实现多线程(PHP多线程类)(转)
查看>>
search-a-2d-matrix——二维矩阵找数
查看>>
lua基础【三】唯一数据结构table表
查看>>
Web应用安全审计工具WATOBO
查看>>
CSS3_animation笔记
查看>>
Android Google 地图 API for Android
查看>>