leoanjos

Aho Corasick

May 23rd, 2023
754
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.45 KB | None | 0 0
  1. template<typename T, typename U, const int SIZE, const int offset>
  2. struct AhoCorasick {
  3. private:
  4.     struct Node {
  5.         int nxt[SIZE];
  6.         int link, slink, id;
  7.         int parent;
  8.         U label;
  9.  
  10.         Node(int parent = -1, U label = '-'): parent(parent), label(label) {
  11.             memset(nxt, -1, sizeof nxt);
  12.             link = slink = id = -1;
  13.         }
  14.  
  15.         int& operator [](U label) {
  16.             return nxt[label - offset];
  17.         }
  18.     };
  19.  
  20.     int size, patterns;
  21.     vector<Node> nodes;
  22.  
  23. public:
  24.     AhoCorasick() {
  25.         size = 1;
  26.         patterns = 0;
  27.         nodes.resize(1);
  28.     }
  29.  
  30.     void insert(T &pattern) {
  31.         int node = 0;
  32.         for (int i = 0; i < (int) pattern.size(); i++) {
  33.             if (nodes[node][pattern[i]] == -1) {
  34.                 nodes[node][pattern[i]] = size++;
  35.                 nodes.emplace_back(node, pattern[i]);
  36.             }
  37.  
  38.             node = nodes[node][pattern[i]];
  39.         }
  40.  
  41.         nodes[node].id = patterns++;
  42.     }
  43.  
  44.     vector<vector<int>> get_matches(T &text) {
  45.         int node = 0;
  46.         vector<vector<int>> matches(text.size(), vector<int>());
  47.  
  48.         for (int i = 0; i < (int) text.size(); i++) {
  49.             node = next(node, text[i]);
  50.             if (nodes[node].id != -1)
  51.                 matches[i].push_back(nodes[node].id);
  52.  
  53.             int curr = next_terminal(node);
  54.             while (curr) {
  55.                 matches[i].push_back(nodes[curr].id);
  56.                 curr = next_terminal(curr);
  57.             }
  58.         }
  59.  
  60.         return matches;
  61.     }
  62.  
  63. private:
  64.     int next(int node, U label) {
  65.         if (nodes[node][label] == -1) {
  66.             if (!node) nodes[node][label] = 0;
  67.             else nodes[node][label] = next(next_suffix(node), label);
  68.         }
  69.  
  70.         return nodes[node][label];
  71.     }
  72.  
  73.     int next_suffix(int node) {
  74.         if (!node || !nodes[node].parent) return 0;
  75.  
  76.         if (nodes[node].link == -1)
  77.             nodes[node].link = next(next_suffix(nodes[node].parent), nodes[node].label);
  78.  
  79.         return nodes[node].link;
  80.     }
  81.  
  82.     int next_terminal(int node) {
  83.         if (!node || !nodes[node].parent) return 0;
  84.  
  85.         if (nodes[node].slink == -1) {
  86.             nodes[node].slink = next_suffix(node);
  87.             if (nodes[node].slink && nodes[nodes[node].slink].id == -1)
  88.                 nodes[node].slink = next_terminal(nodes[node].slink);
  89.         }
  90.  
  91.         return nodes[node].slink;
  92.     }
  93. };
Advertisement
Add Comment
Please, Sign In to add comment