Advertisement
maxim_shlyahtin

Aho-Korasik_1

Aug 7th, 2024
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.20 KB | None | 0 0
  1. #include <iostream>
  2. #include <map>
  3. #include <vector>
  4. #include <string>
  5. #include <array>
  6. #include <utility>
  7. #include <algorithm>
  8.  
  9. const int N = 5;
  10. std::vector<std::string> patterns;
  11. std::array<char, N> alphabet = { 'A', 'C', 'G', 'T', 'N' };
  12.  
  13. struct Node {
  14.     /*std::array<Node*, N> son;
  15.     std::array<Node*, N> go;*/
  16.     std::map<char, Node*> son;
  17.     std::map<char, Node*> go;
  18.     Node* parent;
  19.     Node* suffLink;
  20.     Node* up;
  21.     char charToParent;
  22.     bool isTerminal;
  23.     std::vector<int> leafPatternNumber;
  24.  
  25.     Node() {
  26.         son = { {alphabet[0], NULL}, {alphabet[1], NULL}, {alphabet[2], NULL}, {alphabet[3], NULL}, {alphabet[4], NULL}, };
  27.         go = { {alphabet[0], NULL}, {alphabet[1], NULL}, {alphabet[2], NULL}, {alphabet[3], NULL}, {alphabet[4], NULL}, };
  28.         parent = NULL;
  29.         suffLink = NULL;
  30.         up = NULL;
  31.         charToParent = ' ';
  32.         isTerminal = false;
  33.         //leafPatternNumber = {0};
  34.     }
  35.  
  36. } typedef Node;
  37.  
  38. struct Trie {
  39. public:
  40.     Node* root;
  41.  
  42.     Trie() {
  43.         root = new Node();
  44.     }
  45.  
  46.     Node* getSuffLink(Node* v) {
  47.         //std::cout << "getSuffLink\n";
  48.         if (v->suffLink == NULL) {
  49.             if (v == root || v->parent == root) {
  50.                 v->suffLink = root;
  51.             }
  52.             else {
  53.                 v->suffLink = getLink(getSuffLink(v->parent), v->charToParent);
  54.             }
  55.         }
  56.         //std::cout << "quit getSuffLink\n";
  57.         return v->suffLink;
  58.     }
  59.  
  60.     Node* getLink(Node* v, char c) {
  61.         //std::cout << "getLink" << '\n';
  62.         if (v->go[c] == NULL) {
  63.             if (v->son[c]) {
  64.                 v->go[c] = v->son[c];
  65.             }
  66.             else if (v == root) {
  67.                 v->go[c] = root;
  68.             }
  69.             else {
  70.                 v->go[c] = getLink(getSuffLink(v), c);
  71.             }
  72.         }
  73.         //std::cout << "quit getLink" << '\n';
  74.         return v->go[c];
  75.     }
  76.  
  77.     Node* getUp(Node* v) {
  78.         //std::cout << "getUp\n";
  79.         //std::cout << '\n';
  80.         if (v->up == NULL) {
  81.             if (getSuffLink(v)->isTerminal) {
  82.                 v->up = getSuffLink(v);
  83.             }
  84.             else if (getSuffLink(v) == root) {
  85.                 v->up = root;
  86.             }
  87.             else {
  88.                 v->up = getUp(getSuffLink(v));
  89.             }
  90.         }
  91.         //std::cout << "quit getUp\n";
  92.         return v->up;
  93.     }
  94.  
  95.     void addString(std::string s, int patternNumber) {
  96.         Node* curr = root;
  97.         char c = ' ';
  98.         for (size_t i = 0; i < s.length(); ++i) {
  99.             c = s[i];
  100.             if (curr->son[c] == NULL) {
  101.                 curr->son[c] = new Node();
  102.                 //curr->son[c]->suffLink = NULL;
  103.                 //curr->son[c]->up = NULL;
  104.                 curr->son[c]->parent = curr;
  105.                 curr->son[c]->charToParent = c;
  106.                 //curr->son[c]->isTerminal = false;
  107.             }
  108.             curr = curr->son[c];
  109.             //std::cout << curr->charToParent << '\n';
  110.         }
  111.         //std::cout << c << '\n';
  112.         curr->isTerminal = true;
  113.         curr->leafPatternNumber.push_back(patternNumber);
  114.     }
  115.  
  116.     void check(Node* v, int i) {
  117.         Node* u = v;
  118.         //std::cout << "check\n";
  119.         while (u != root) {
  120.             if (u->isTerminal) {
  121.                 //std::cout << i - patterns[u->leafPatternNumber[i]].length() + 1 << " " << patterns[u->leafPatternNumber[i]] << '\n';
  122.             }
  123.             u = getUp(u);
  124.         }
  125.         //std::cout << "quit check\n";
  126.     }
  127.  
  128.     void find_all_pos(std::string& t) {
  129.         Node* u = root;
  130.         //std::cout << 1 << '\n';
  131.         for (size_t i = 0; i < t.length(); ++i) {
  132.             u = getLink(u, t[i]);
  133.             Node* checkNode = u;
  134.             check(checkNode, i + 1);
  135.         }
  136.     }
  137.  
  138.     void process_text(std::string& s, std::vector<std::pair<int, int>>& ans) {
  139.         Node* curr = root;
  140.         for (size_t i = 0; i < s.length(); ++i) {
  141.             char c = s[i];
  142.             curr = getLink(curr, c);
  143.             Node* checkNode = curr;
  144.             while (checkNode != root) {
  145.                 if(checkNode->isTerminal){
  146.                     for (auto& patNum : checkNode->leafPatternNumber) {
  147.                         //std::cout << i + 2 - patterns[patNum].length() << " " << patNum + 1 << '\n';
  148.                         ans.push_back(std::make_pair(i + 2 - patterns[patNum].length(), patNum + 1));
  149.                     }
  150.                 }
  151.                 checkNode = getUp(checkNode);
  152.             }
  153.         }
  154.     }
  155.  
  156.  
  157.     ~Trie() = default;
  158.  
  159. } typedef Trie;
  160.  
  161. int main() {
  162.     Trie tr;
  163.     //patterns = { "TAGT", "TAG", "T"};
  164.     std::string t;
  165.     std::cin >> t;
  166.     int n;
  167.     std::cin >> n;
  168.     for (size_t i = 0; i < n; ++i) {
  169.         std::string  str;
  170.         std::cin >> str;
  171.         patterns.push_back(str);
  172.     }
  173.  
  174.     for (size_t i = 0; i < patterns.size(); ++i) {
  175.         tr.addString(patterns[i], i);
  176.     }
  177.     std::vector<std::pair<int, int>> ans;
  178.     tr.process_text(t, ans);
  179.     std::sort(ans.begin(), ans.end());
  180.     for (const auto& it : ans) {
  181.         std::cout << it.first << ' ' << it.second << '\n';
  182.     }
  183.     return 0;
  184. }
  185.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement