Advertisement
MystMe

Untitled

Mar 18th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.56 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5. const int ALPHABET_SIZE = 256; // размер алфавита
  6.  
  7. vector<int> build_suffix_array(const string& origin_string){
  8.     const size_t STRING_SIZE = origin_string.size();
  9.     vector<int> suffix_array(STRING_SIZE);
  10.     vector<int> buckets(ALPHABET_SIZE);
  11.     vector<int> classes (STRING_SIZE);
  12.  
  13.     for (auto i=0; i<STRING_SIZE; i++) {
  14.         buckets[origin_string[i]]++;
  15.     }
  16.     for (auto i=1; i<ALPHABET_SIZE; i++) {
  17.         buckets[i] += buckets[i - 1];
  18.     }
  19.     for (auto i=0; i<STRING_SIZE; i++) {
  20.         buckets[origin_string[i]]--;
  21.         suffix_array[buckets[origin_string[i]]] = i;
  22.     }
  23.  
  24.     classes[suffix_array[0]] = 0;
  25.     int num_of_class = 1;
  26.     for (auto i = 1; i < STRING_SIZE; i++) {
  27.         if (origin_string[suffix_array[i]] != origin_string[suffix_array[i-1]]) {
  28.             num_of_class++;
  29.         }
  30.         classes[suffix_array[i]] = num_of_class-1;
  31.     }
  32.  
  33.     vector<int> tmp_buckets(ALPHABET_SIZE);
  34.     vector<int> tmp_classes(ALPHABET_SIZE);
  35.     for (auto h=0; (1<<h) < STRING_SIZE; h++) {
  36.         for (size_t  i=0; i<STRING_SIZE; i++) {
  37.             tmp_buckets[i] = suffix_array[i] - (1<<h);
  38.             if (tmp_buckets[i] < 0) {
  39.                 tmp_buckets[i] += STRING_SIZE;
  40.             }
  41.         }
  42.  
  43.         buckets.assign(STRING_SIZE,0);
  44.         for (auto  i=0; i<STRING_SIZE; i++) {
  45.             buckets[classes[tmp_buckets[i]]]++;
  46.         }
  47.         for (auto  i=1; i<num_of_class; i++) {
  48.             buckets[i] += buckets[i - 1];
  49.         }
  50.         for (auto i = int(STRING_SIZE)-1; i>=0; i--) {
  51.             suffix_array[--buckets[classes[tmp_buckets[i]]]] = tmp_buckets[i];
  52.         }
  53.  
  54.         tmp_classes[suffix_array[0]] = 0;
  55.         num_of_class = 1;
  56.         for (auto i=1; i<STRING_SIZE; i++) {
  57.             size_t first = (suffix_array[i] + (1<<h)) % STRING_SIZE;
  58.             size_t second = (suffix_array[i-1] + (1<<h)) % STRING_SIZE;
  59.             if (classes[suffix_array[i]] != classes[suffix_array[i-1]] || classes[first] != classes[second]) {
  60.                 ++num_of_class;
  61.             }
  62.             tmp_classes[suffix_array[i]] = num_of_class-1;
  63.         }
  64.         for(int i = 0; i < STRING_SIZE; i++){
  65.             classes[i] = tmp_classes[i];
  66.         }
  67.     }
  68.     return suffix_array;
  69. }
  70. vector<int> build_LCP(const string &str,const vector<int>& suf){
  71.     size_t size = str.size();
  72.     vector<int> lcp (size);
  73.     vector<int> pos (size);
  74.     for(int i = 0; i < size-1 ; i++){
  75.         pos[suf[i]] = i;
  76.     }
  77.     int num = 0;
  78.     for(auto i = 0; i < size-1; i++){
  79.         if(num > 0){
  80.             num--;
  81.         }
  82.         if(pos[i] == size-1){
  83.             lcp[size-1] = -1;
  84.             num = 0;
  85.         }
  86.         else{
  87.             int tmp = suf[pos[i]+1];
  88.             while( (max(i+num,tmp+num) < size) && (str[i+num] == str[tmp+num] ) ){
  89.                 num++;
  90.             }
  91.             lcp[pos[i]] = num;
  92.         }
  93.     }
  94.     return lcp;
  95. }
  96. int main() {
  97.     string origin_string;   //  Исходная строка
  98.     cin >> origin_string;
  99.  
  100.     origin_string += '$';
  101.  
  102.     vector<int> suffix_array = build_suffix_array(origin_string);   // Строим массив суффиксов
  103.     vector<int> LCP = build_LCP(origin_string, suffix_array);       // Longest common prefix
  104.  
  105.     int seq_number = 0;    // Количество подстрок
  106.     size_t size = origin_string.size();
  107.     for(int i = 0; i < size; i++){
  108.         seq_number += (size-1) - suffix_array[i] - LCP[i];
  109.     }
  110.     cout << seq_number;
  111.     return 0;
  112. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement