Advertisement
Guest User

Untitled

a guest
Jan 30th, 2018
1,020
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.71 KB | None | 0 0
  1. struct ahocorasick {
  2.     vector<vector<int>> next;
  3.     vector<int> fail, out, finish, cnt;
  4.     vector<string> words;
  5.     // if there are repeated words and it is necessary to show them
  6.     // 'finish' has to be vector<vector<int>>
  7.     ahocorasick () {
  8.         next.push_back(vector<int>(26));
  9.         finish.push_back(0);
  10.         cnt.push_back(0);
  11.     }
  12.     void insert (string &s) {
  13.         int u = 0;
  14.         for (int i = 0; i < s.size(); ++i) {
  15.             int c = s[i] - 'a';
  16.             if (!next[u][c]) {
  17.                 next[u][c] = next.size();
  18.                 next.push_back(vector<int>(26));
  19.                 finish.push_back(-1);
  20.                 cnt.push_back(0);
  21.             }
  22.             u = next[u][c];
  23.         }
  24.         finish[u] = words.size();
  25.         ++cnt[u];
  26.         words.push_back(s);
  27.     }
  28.     int get_fail (int pfail, int c) {
  29.         while (!next[pfail][c] && pfail != 0)
  30.             pfail = fail[pfail];
  31.         return next[pfail][c];
  32.     }
  33.     void update_out (int u) {
  34.         out[u] = fail[u];
  35.         while (finish[out[u]] == -1)
  36.             out[u] = fail[out[u]];
  37.     }
  38.     void buildf () {
  39.         queue<int> q;
  40.         fail.assign(next.size(), 0);
  41.         out.assign(next.size(), 0);
  42.         for (int i = 0; i < 26; ++i)
  43.             if(next[0][i]) q.push(next[0][i]);
  44.         while (q.size()) {
  45.             int u = q.front();
  46.             q.pop();
  47.             for (int i = 0; i < 26; ++i) {
  48.                 int v = next[u][i];
  49.                 if (v) {
  50.                     fail[v] = get_fail(fail[u], i);
  51.                     cnt[v] += cnt[ fail[v] ];
  52.                     q.push(v);
  53.                     update_out(v);
  54.                 }
  55.             }
  56.         }
  57.     }
  58.     int match (string &s) {
  59.         int cur = 0, matches = 0;
  60.         for (int i = 0; i < s.size(); ++i) {
  61.             int c = s[i] - 'a';
  62.             if (next[cur][c]) cur = next[cur][c];
  63.             else cur = get_fail(fail[cur], c);
  64.             matches += cnt[cur];
  65.             int t = cur;
  66.             while (t != 0) {
  67.                 if (finish[t] != -1)
  68.                     cout << words[ finish[t] ] << endl;
  69.                 t = out[t];
  70.             }
  71.         }
  72.         return matches;
  73.     }
  74. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement