后缀数组笔记

本文介绍了一种使用倍增法高效构建后缀数组的方法,并提供了完整的C++实现代码。该方法首先初始化字符级别后缀数组,然后通过比较前后缀来逐步增加长度并更新排名,最终得到完整的后缀数组及高度数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

倍增求后缀数组

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 int rank[10001],sa[10001],height[10001],buc[10001],x[10001],y[10001],n,len;
 7 char st[10001]; 
 8 bool cmp(int *s,int n,int m,int x){
 9     return s[n]==s[m]&&s[n+x]==s[m+x];
10 }
11 void initsa(int n,int m){
12     memset(buc,0,sizeof(buc));
13     for(int i=0;i<n;i++)buc[x[i]=st[i]]++;
14     for(int i=1;i<m;i++)buc[i]+=buc[i-1];
15     for(int i=len-1;i>=0;i--)sa[--buc[x[i]]]=i;
16     for(int j=1,p=1;p<n;j*=2,m=p){
17         p=0;
18         for(int i=n-j;i<n;i++)y[p++]=i;
19         for(int i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
20         memset(buc,0,sizeof(buc));
21         for(int i=0;i<n;i++)buc[x[y[i]]]++;
22         for(int i=1;i<m;i++)buc[i]+=buc[i-1];
23         for(int i=n-1;i>=0;i--)sa[--buc[x[y[i]]]]=y[i];
24         swap(x,y);
25         int i;
26         for(p=1,x[sa[0]]=0,i=1;i<n;i++){
27             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
28         }
29     }
30 }
31 void initra(){
32     for(int i=0;i<len;i++)rank[sa[i]]=i;
33 }
34 void initheight(){
35     int j,k=0;
36     for(int i=0;i<len;i++){
37         if(k)k--;
38         j=sa[rank[i]-1];
39         while(st[i+k]==st[j+k])k++;
40         height[rank[i]]=k;
41     }
42 }
43 int main(){
44     scanf("%s",st);
45     len=(int)strlen(st);
46     initsa(len,128);
47     initra();
48     initheight();
49     for(int i=0;i<len;i++){
50         printf("%d",rank[i]);
51     }
52     printf("\n");
53     for(int i=0;i<len;i++){
54         printf("%d",sa[i]);
55     }
56     printf("\n");
57     for(int i=0;i<len;i++){
58         printf("%d",height[i]);
59     }
60     return 0;
61 }

 

转载于:https://www.cnblogs.com/dcdcbigbig/p/8952219.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值