zoukankan      html  css  js  c++  java
  • SA后缀数组

    需要再多去理解

      1 #include<cstdio> 
      2 #include<cstring>
      3 #include<cmath>
      4 #include<ctime>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<set>
      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<n;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?'
    ':' ');
     73     }*/
     74     rep(i,1,n){
     75         printf("%d",sa[i]);
     76         putchar(i==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?'
    ':' ');
     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
  • 相关阅读:
    83. Remove Duplicates from Sorted List
    35. Search Insert Position
    96. Unique Binary Search Trees
    94. Binary Tree Inorder Traversal
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    111. Minimum Depth of Binary Tree
    169. Majority Element
    171. Excel Sheet Column Number
    190. Reverse Bits
  • 原文地址:https://www.cnblogs.com/chensiang/p/7868485.html
Copyright © 2011-2022 走看看