Advertisement
istinishat

Suffix array

Sep 21st, 2017
252
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /***************************************************************************************
  2.  *     Suffix Array Implementation O(nlog n)
  3.  *     Definition : suffix(i) => substring [i,n-1]
  4.  *     Input : STRING (inpStr) , sigma => Character Set Size
  5.  Output:
  6.  sa => ith smallest suffix of the string
  7.  rak => rak[i] indicates the position of suffix(i) in the suffix array
  8.  height => height[i] indicates the LCP of i-1 and i th suffix
  9.  *     LCP of suffix(i) & suffix(j) = { L = rak[i], R = rak[j] ,  min(height[L+1, R]);}
  10.  ***************************************************************************************/
  11. #include<bits/stdc++.h>
  12. using namespace std;
  13.  
  14.  
  15. const int M = 100001;
  16. char s[M];
  17. int wa[M],wb[M],wv[M],wc[M];
  18. int r[M],sa[M],rak[M], height[M],dp[M][22], SIGMA = 0 ;
  19. int logg[M];
  20.  
  21. int cmp(int *r,int a,int b,int l){return r[a] == r[b] && r[a+l] == r[b+l];}
  22. void da(int *r,int *sa,int n,int m)
  23. {
  24.     int i,j,p,*x=wa,*y=wb,*t;
  25.     for( i=0;i<m;i++) wc[i]=0;
  26.     for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
  27.     for( i=1;i<m;i++) wc[i] += wc[i-1];
  28.     for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
  29.     for( j= 1,p=1;p<n;j*=2,m=p){
  30.         for(p=0,i=n-j;i<n;i++)y[p++] = i;
  31.         for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
  32.         for(i=0;i<n;i++)wv[i] = x[y[i]];
  33.         for(i=0;i<m;i++) wc[i] = 0;
  34.         for(i=0;i<n;i++) wc[wv[i]] ++;
  35.         for(i=1;i<m;i++) wc[i] += wc[i-1];
  36.         for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
  37.         for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
  38.     }
  39. }
  40. void calheight(int *r,int *sa,int n)
  41. {
  42.     int i,j,k=0;
  43.     for(i=1;i<=n;i++) rak[sa[i]] = i;
  44.     for(i=0;i<n;height[rak[i++]] = k ) {
  45.         for(k?k--:0, j=sa[rak[i]-1] ; r[i+k] == r[j+k] ; k ++) ;
  46.     }
  47. }
  48.  
  49. void initRMQ(int n)
  50. {
  51.     for(int i= 1;i<=n;i++) dp[i][0] = height[i];
  52.     for(int j= 1; (1<<j) <= n; j ++ ){
  53.         for(int i = 1; i + (1<<j) - 1 <= n ; i ++ ) {
  54.             dp[i][j] = min(dp[i][j-1] , dp[i + (1<<(j-1))][j-1]);
  55.         }
  56.     }
  57.     for (int i=0; i<M; i++)
  58.     {
  59.         logg[i] = 0;
  60.         while((1<<(logg[i]+1)) <= i) logg[i]++;;
  61.     }
  62. }
  63. int askRMQ(int L,int R)
  64. {
  65.     int k = logg[R-L+1];
  66.     return min(dp[L][k], dp[R - (1<<k) + 1][k]);
  67. }
  68.  
  69. //input starting index of two substring
  70. //ex: aaba,input:0,1 :output: 1
  71.  
  72. int askLCP(int L, int R)
  73. {
  74.     if (rak[L] > rak[R]) swap(L, R);
  75.     return askRMQ(rak[L]+1, rak[R]);
  76. }
  77.  
  78.  
  79. int main()
  80. {
  81.     sscanf("aabaaba", "%s",s);
  82.     int n = strlen(s);
  83.     for(int i = 0; i < n; i ++) {
  84.         r[i] = s[i]-'a' + 1;
  85.         SIGMA = max(SIGMA, r[i]);
  86.     }
  87.     r[n] = 0;
  88.     da(r,sa,n+1,SIGMA + 1);
  89.     calheight(r,sa,n);
  90.     initRMQ(n);
  91.  
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement