Advertisement
maiden18

Suffix Array

Aug 10th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.84 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define MAX 1000005
  4.  
  5. int wa[MAX],wb[MAX],wv[MAX],Ws[MAX];
  6. int cmp(int *r,int a,int b,int l) {return r[a]==r[b] && r[a+l]==r[b+l];}
  7.  
  8. //(1-indexed) sa[i] = starting position (0...n-1) of ith lexicographically smallest suffix in s
  9. //(0-indexed) Rank[i] = lexicographical rank of s[i....n-1] ((i+1)th suffix by position)
  10. //LCP[i] = longest common prefix of sa[i] & sa[i-1]
  11. int sa[MAX],Rank[MAX],LCP[MAX];
  12.  
  13. //Suffix Array (O(nlogn))
  14. //m = maximum possible ASCII value of a string character (alphabet size)
  15. //also, m = maximum number of distinct character in string (when compressed)
  16. void buildSA(string s,int* sa,int n,int m){
  17.     int i,j,p,*x=wa,*y=wb,*t;
  18.     for(i=0; i<m; i++) Ws[i]=0;
  19.     for(i=0; i<n; i++) Ws[x[i]=s[i]]++;
  20.     for(i=1; i<m; i++) Ws[i]+=Ws[i-1];
  21.     for(i=n-1; i>=0; i--) sa[--Ws[x[i]]]=i;
  22.     for(j=1,p=1; p<n; j<<=1,m=p){
  23.         for(p=0,i=n-j; i<n; i++) y[p++]=i;
  24.         for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
  25.         for(i=0; i<n; i++) wv[i]=x[y[i]];
  26.         for(i=0; i<m; i++) Ws[i]=0;
  27.         for(i=0; i<n; i++) Ws[wv[i]]++;
  28.         for(i=1; i<m; i++) Ws[i]+=Ws[i-1];
  29.         for(i=n-1; i>=0; i--) sa[--Ws[wv[i]]]=y[i];
  30.         for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)
  31.             x[sa[i]]=cmp(y,sa[i-1],sa[i],j) ? p-1 : p++;
  32.     }
  33. }
  34.  
  35. //Kasai's LCP algorithm (O(n))
  36. void buildLCP(string s,int *sa,int n){
  37.     int i,j,k=0;
  38.     for(i=1; i<=n; i++) Rank[sa[i]]=i;
  39.     for(i=0; i<n; LCP[Rank[i++]]=k)
  40.         for(k?k--:0, j=sa[Rank[i]-1]; s[i+k]==s[j+k]; k++);
  41.     return;
  42. }
  43.  
  44. int main(){
  45.     string s="abababab";
  46.     int n=s.size();
  47.     buildSA(s,sa,n+1,130); //Important
  48.     buildLCP(s,sa,n);
  49.     for(int i=1;i<=n;i++) cout<<sa[i]<<" "; cout<<endl;
  50.     for(int i=0;i<n;i++) cout<<Rank[i]<<" "; cout<<endl;
  51.     for(int i=1;i<=n;i++) cout<<LCP[i]<<" ";
  52. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement