Advertisement
LinKin

Suffix array

Nov 17th, 2011
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.23 KB | None | 0 0
  1. /*
  2.  *  Algorithm: Suffix array
  3.  *  Order: nlogn
  4. */
  5.  
  6. #include<stdio.h>
  7. #include<string.h>
  8. #include<vector>
  9. #include<algorithm>
  10. using namespace std;
  11.  
  12. #define MAX 200007
  13.  
  14. struct DATA{
  15.     long Val[2];
  16.     long Ind;
  17. };
  18. /* is needed if qsort is used */
  19. bool operator<( const DATA &a,const DATA &b )
  20. {
  21.     if( a.Val[0] != b.Val[0] ) return a.Val[0] < b.Val[0];
  22.     else return a.Val[1] < b.Val[1];
  23. }
  24. char Str[MAX+7];
  25. long Len;
  26. long Buc[22][MAX+7];
  27. long SuffA[MAX+7]; // will contain index of all suffix in sorted order
  28. long Stp;        
  29.  
  30. long Cnt[MAX+7],Cum[MAX+7];
  31.  
  32. void CountSort( vector<DATA> &Inf,long I )
  33. {
  34.     // max is used to count max val is used
  35.     // +1 adding is needed to handle -1
  36.     long i,Max = 0;
  37.     for( i=0;i<Inf.size();i++){
  38.         if( Max < Inf[i].Val[I] + 1 ) Max = Inf[i].Val[I] + 1;
  39.     }
  40.  
  41.     memset( Cnt,0,(Max+1)*sizeof(long));
  42.     for( i=0;i<Inf.size();i++){
  43.         Cnt[Inf[i].Val[I] + 1 ]++;
  44.     }
  45.  
  46.     Cum[0] = Cnt[0];
  47.     for( i=1;i<=Max;i++){
  48.         Cum[i] = Cum[i-1] + Cnt[i];
  49.     }
  50.  
  51.     vector<DATA> Tmp;
  52.     Tmp.resize( Inf.size());
  53.     for( i=Inf.size()-1;i>=0;i--){
  54.         Cum[ Inf[i].Val[I] + 1 ]--;
  55.         Tmp[ Cum[ Inf[i].Val[I] +1 ] ] = Inf[i];
  56.        
  57.     }
  58.     Inf = Tmp;
  59. }
  60.  
  61. void SuffArrCreate( void )
  62. {
  63.     long i,j;
  64.  
  65.     for( i=0;i<Len;i++){
  66.         Buc[0][i] = Str[i];
  67.     }
  68.     vector<DATA> Inf;
  69.     Inf.resize( Len );
  70.     long c;
  71.     for( c=1,Stp=1;c < Len;c<<=1,Stp++ ){
  72.  
  73.         for( j=0;j<Len;j++){
  74.             Inf[j].Val[0] = Buc[Stp-1][j];
  75.             Inf[j].Val[1] = j+c < Len ? Buc[Stp-1][j+c]:-1;
  76.             Inf[j].Ind = j;
  77.         }
  78.         // if O( nlogn^2 ) pos
  79.         //sort( Inf.begin(),Inf.end());
  80.         CountSort( Inf , 1 );
  81.         CountSort( Inf , 0 );
  82.  
  83.         Buc[Stp][Inf[0].Ind] = 0;
  84.         for( j=1;j<Inf.size();j++){
  85.             if( Inf[j].Val[0]==Inf[j-1].Val[0] && Inf[j].Val[1]==Inf[j-1].Val[1] ) Buc[Stp][Inf[j].Ind] = Buc[Stp][Inf[j-1].Ind];
  86.             else{
  87.                 Buc[Stp][Inf[j].Ind] = j;
  88.             }
  89.         }
  90.     }
  91.     Stp--;
  92.     for( i=0;i<Len;i++){
  93.         SuffA[Buc[Stp][i]] = i;
  94.     }
  95.  
  96. }
  97. // fining longest common pref lenth of two suffix in O(longn)
  98. long Lcp( long i,long j )
  99. {
  100.     long k,Tot = 0;
  101.     for( k=Stp;k>=0 && i<Len && j<Len;k--){
  102.         if( Buc[k][i]==Buc[k][j] ){
  103.             i += 1<<k;
  104.             j += 1<<k;
  105.             Tot += 1<<k;
  106.         }
  107.     }
  108.     return Tot;
  109. }
  110.  
  111. int main( void )
  112. {
  113.     scanf("%s",Str );
  114.     Len = strlen(Str);
  115.     SuffArrCreate();
  116.     return 0;
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement