-
Notifications
You must be signed in to change notification settings - Fork 46
/
aho_corasick.cpp
50 lines (44 loc) · 959 Bytes
/
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
const int K = 20;
struct vertex {
vertex *next[K], *go[K], *link, *p;
int pch;
bool leaf;
int is_accepting = -1;
};
vertex *create() {
vertex *root = new vertex();
root->link = root;
return root;
}
void add_string (vertex *v, const vector<int>& s) {
for (int a: s) {
if (!v->next[a]) {
vertex *w = new vertex();
w->p = v;
w->pch = a;
v->next[a] = w;
}
v = v->next[a];
}
v->leaf = 1;
}
vertex* go(vertex* v, int c);
vertex* get_link(vertex *v) {
if (!v->link)
v->link = v->p->p ? go(get_link(v->p), v->pch) : v->p;
return v->link;
}
vertex* go(vertex* v, int c) {
if (!v->go[c]) {
if (v->next[c])
v->go[c] = v->next[c];
else
v->go[c] = v->p ? go(get_link(v), c) : v;
}
return v->go[c];
}
bool is_accepting(vertex *v) {
if (v->is_acceping == -1)
v->is_accepting = get_link(v) == v ? false : (v->leaf || is_accepting(get_link(v)));
return v->is_accepting;
}