-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathaho_corasick.cpp
56 lines (45 loc) · 1.28 KB
/
aho_corasick.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
namespace aho {
const int M = 3e5 + 1;
const int K = 26;
const char norm = 'a';
inline int get(int c) { return c - norm; }
int next[M][K], link[M], out_link[M], par[M], cur = 2;
char pch[M];
bool out[M];
vector<int> output[M];
int node(int p, char c) {
link[cur] = out_link[cur] = 0;
par[cur] = p;
pch[cur] = c;
return cur++;
}
int T = 0;
int insert(const string &s) {
int u = 1;
for (int i = 0; i < (int)s.size(); i++) {
auto v = next[u][get(s[i])];
if (v == 0) next[u][get(s[i])] = v = node(u, s[i]);
u = v;
}
out[u] = true;
output[u].emplace_back(T);
return T++;
}
int go(int u, char c);
int get_link(int u) {
if (link[u] == 0) link[u] = par[u] > 1 ? go(get_link(par[u]), pch[u]) : 1;
return link[u];
}
int go(int u, char c) {
if (next[u][get(c)] == 0) next[u][get(c)] = u > 1 ? go(get_link(u), c) : 1;
return next[u][get(c)];
}
int exit(int u) {
if (out_link[u] == 0) {
int v = get_link(u);
out_link[u] = (out[v] || v == 1) ? v : exit(v);
}
return out_link[u];
}
bool matched(int u) { return out[u] || exit(u) > 1; }
}