Advertisement
Guest User

Suffix Tree

a guest
Apr 6th, 2020
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <cmath>
  5. #include <climits>
  6. #include <unordered_set>
  7. #include <set>
  8. #include <map>
  9. #include <iomanip>
  10. #include <cstdlib>
  11. #include <string>
  12. #include <cstring>
  13. #include <fstream>
  14. #include <cstdio>
  15. #include <sstream>
  16. #include <clocale>
  17.  
  18. using namespace std;
  19.  
  20.  
  21.  
  22. struct vertex {
  23.     struct edge {
  24.         int l, siz;
  25.         vertex* to;
  26.         edge(int l = 0, int siz = 0, vertex* to = nullptr) : l(l), siz(siz), to(to) {}
  27.     };
  28.     vertex* par;
  29.     char par_c;
  30.     map<char, edge> links;
  31.     map<char, vertex*> pref_links;
  32.     vertex(vertex* par = nullptr) : par(par) {}
  33. };
  34.  
  35. void build(string& s, vertex* t) {
  36.     s.push_back('$');
  37.     int n = s.length();
  38.     vertex* last_vertex = t;
  39.     vector<vertex*> stack;
  40.     stack.reserve(n);
  41.     for (int i = n - 1; i > -1; i--) {
  42.         int now_height = n - i;
  43.         while (!last_vertex->pref_links.count(s[i])) {
  44.             stack.push_back(last_vertex);
  45.             now_height -= last_vertex->par->links[last_vertex->par_c].siz;
  46.             last_vertex = last_vertex->par;
  47.         }
  48.        
  49.         vertex* w = last_vertex->pref_links[s[i]];
  50.         int to_split = 0;
  51.         if (!w->links.count(s[i + now_height])) {
  52.             vertex* tmp = new vertex(w);
  53.             tmp->par_c = s[i + now_height];
  54.             w->links[s[i]] = vertex::edge(i, n - i - now_height, tmp);
  55.             stack[0]->pref_links[s[i]] = tmp;
  56.             last_vertex = tmp;
  57.             stack.clear();
  58.             continue;
  59.         }
  60.         //if ((*stack.rbegin())->par_c == '$')
  61.         //  stack.pop_back();
  62.         vertex::edge u = w->links[s[i + now_height]];
  63.         vertex* last = nullptr;
  64.         int a = 0;
  65.         for (; !stack.empty() && s[i + now_height] == s[u.l + to_split];) {
  66.             a = (*stack.rbegin())->par->links[(*stack.rbegin())->par_c].siz;
  67.             to_split += a;
  68.             now_height += a;
  69.             last = stack.back();
  70.             stack.pop_back();
  71.         }
  72.         stack.push_back(last);
  73.         if (to_split == 0) {
  74.             vertex* tmp = new vertex(w);
  75.             tmp->par_c = s[i + now_height];
  76.             w->links[s[i + now_height]] = vertex::edge(i + now_height, n - i - now_height, tmp);
  77.             if (!stack.empty())
  78.                 stack[0]->pref_links[s[i]] = tmp;
  79.             last_vertex = tmp;
  80.         }
  81.         else {
  82.             vertex* tmp = new vertex(w);
  83.             vertex* tmp2 = new vertex(w);
  84.             tmp2->links[s[u.l + to_split]] = vertex::edge(u.l + to_split, w->links[s[i + now_height]].siz - to_split, u.to);
  85.             u.to->par = tmp2;
  86.             u.to->par_c = s[u.l + to_split];
  87.             w->links[s[i + now_height]].siz = to_split;
  88.             w->links[s[i + now_height]].to = tmp2;
  89.             tmp2->par_c = s[u.l];
  90.             tmp2->links[s[i + now_height]] = vertex::edge(i + now_height, (n - i) - (now_height + 1 - to_split), tmp);
  91.             tmp->par_c = s[i + now_height];
  92.             tmp->par = tmp2;
  93.             (*stack.rbegin())->pref_links[s[i]] = tmp2;
  94.             stack[0]->pref_links[s[i]] = tmp;
  95.             last_vertex = tmp;
  96.         }
  97.        
  98.         stack.clear();
  99.     }
  100. }
  101.  
  102. signed main() {
  103.     string s;
  104.     vertex* fictive = new vertex();
  105.     vertex* t = new vertex();
  106.     for (char i = 'A'; i < 'z'; i++) {
  107.         fictive->pref_links[i] = t;
  108.         fictive->links[i] = vertex::edge(0, 1, t);
  109.     }
  110.     t->par_c = 'A';
  111.     t->par = fictive;
  112.     fictive->pref_links['$'] = t;
  113.     //cin >> s;
  114.     s = "mississippi";
  115.     build(s, t);
  116.     t;
  117.     return 0;
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement