Advertisement
Guest User

Untitled

a guest
Mar 4th, 2012
7,554
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.59 KB | None | 0 0
  1. // lexicographic order for pairs
  2. inline bool leq(int a1, int a2, int b1, int b2) {
  3.     return(a1 < b1 || a1 == b1 && a2 <= b2);
  4. }
  5.  
  6. // and triples
  7. inline bool leq(int a1, int a2, int a3, int b1, int b2, int b3) {
  8.     return(a1 < b1 || a1 == b1 && leq(a2,a3, b2,b3));
  9. } // and triples
  10.  
  11. // stably sort a[0..n-1] to b[0..n-1] with keys in 0..K from r
  12. static void radixPass(int* a, int* b, int* r, int n, int K) {// count occurrences
  13.     int* c = new int[K + 1]; // counter array
  14.     for (int i = 0; i <= K; i++) c[i] = 0; // reset counters
  15.     for (int i = 0; i < n; i++) c[r[a[i]]]++; // count occurrences
  16.     for (int i = 0, sum = 0; i <= K; i++) // exclusive prefix sums
  17.     {
  18.         int t = c[i];
  19.         c[i] = sum;
  20.         sum += t;
  21.     }
  22.     for (int i = 0;  i < n; i++) b[c[r[a[i]]]++] = a[i]; // sort
  23.     delete [] c;
  24. }
  25.  
  26. // find the suffix array SA of s[0..n-1] in {1..K}ˆn
  27. // require s[n]=s[n+1]=s[n+2]=0, n>=2
  28. void suffixArray(int* s, int* SA, int n, int K) {
  29.     int n0 = (n+2)/3, n1 = (n+1)/3, n2 = n/3, n02 = n0+n2;
  30.     int* s12 = new int[n02+3]; s12[n02] = s12[n02+1] = s12[n02+2] = 0;
  31.     int* SA12 = new int[n02+3]; SA12[n02] = SA12[n02+1] = SA12[n02+2] = 0;
  32.     int* s0 = new int[n0];
  33.     int* SA0 = new int[n0];
  34.     // generate positions of mod 1 and mod 2 suffixes
  35.     // the "+(n0-n1)" adds a dummy mod 1 suffix if n%3 == 1
  36.     for (int i=0, j=0; i < n + (n0-n1); i++)
  37.         if (i%3 != 0) s12[j++] = i;
  38.     // lsb radix sort the mod 1 and mod 2 triples
  39.     radixPass(s12 , SA12, s+2, n02, K);
  40.     radixPass(SA12, s12 , s+1, n02, K);
  41.     radixPass(s12 , SA12, s  , n02, K);
  42.     // find lexicographic names of triples
  43.     int name = 0, c0 = -1, c1 = -1, c2 = -1;
  44.     for (int i = 0; i < n02; i++) {
  45.         if (s[SA12[i]] != c0 || s[SA12[i]+1] != c1 || s[SA12[i]+2] != c2) {
  46.             name++;
  47.             c0 = s[SA12[i]];
  48.             c1 = s[SA12[i]+1];
  49.             c2 = s[SA12[i]+2];
  50.         }
  51.         if (SA12[i]%3 == 1) s12[SA12[i]/3] = name; // left half
  52.         else s12[SA12[i]/3 + n0] = name; // right half
  53.     }
  54.     // recurse if names are not yet unique
  55.     if (name < n02) {
  56.         suffixArray(s12, SA12, n02, name);
  57.         // store unique names in s12 using the suffix array
  58.         for (int i = 0; i < n02; i++) s12[SA12[i]] = i + 1;
  59.     } else // generate the suffix array of s12 directly
  60.         for (int i = 0;  i < n02; i++) SA12[s12[i] - 1] = i;
  61.     // stably sort the mod 0 suffixes from SA12 by their first character
  62.     for (int i = 0, j = 0; i < n02; i++)
  63.         if (SA12[i] < n0) s0[j++] = 3*SA12[i];
  64.     radixPass(s0, SA0, s, n0, K);
  65.     // merge sorted SA0 suffixes and sorted SA12 suffixes
  66.     for (int p = 0, t = n0-n1, k = 0; k < n; k++) {
  67.         #define GetI() (SA12[t] < n0 ? SA12[t] * 3 + 1 : (SA12[t] - n0) * 3 + 2)
  68.         int i = GetI(); // pos of current offset 12 suffix
  69.         int j = SA0[p]; // pos of current offset 0 suffix
  70.         if (SA12[t] < n0 ? // different compares for mod 1 and mod 2 suffixes
  71.             leq(s[i], s12[SA12[t] + n0], s[j], s12[j/3]) :
  72.             leq(s[i],s[i+1],s12[SA12[t]-n0+1], s[j],s[j+1],s12[j/3+n0]))
  73.         {// suffix from SA12 is smaller
  74.             SA[k] = i; t++;
  75.             if (t == n02) // done --- only SA0 suffixes left
  76.             for (k++; p < n0; p++, k++) SA[k] = SA0[p];
  77.         } else {// suffix from SA0 is smaller
  78.             SA[k] = j; p++;
  79.             if (p == n0) // done --- only SA12 suffixes left
  80.             for (k++; t < n02; t++, k++) SA[k] = GetI();
  81.         }
  82.     }
  83.     delete [] s12; delete [] SA12; delete [] SA0; delete [] s0;
  84. }
  85.  
  86. int main() {
  87.  
  88.     return 0;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement