Skip to content

Commit 629d89d

Browse files
committed
add Aho–Corasick algorithm
1 parent 25f2604 commit 629d89d

File tree

2 files changed

+118
-1
lines changed

2 files changed

+118
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Collections of some commonly used algorithms.
1414
+ [x] 后缀树
1515
+ [x] 后缀自动机
1616
+ [x] 子序列自动机
17-
+ [ ] AC自动机
17+
+ [x] AC自动机
1818
+ [x] Palindromic Factorization
1919
+ [x] Lyndon Word Factorization
2020
+ [ ] Square Factorization

string-utility/Aho-Corasick.cc

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <bits/stdc++.h>
2+
3+
struct AhoCorasick {
4+
static const int MAXL = 1e5 + 10, C = 26;
5+
struct node {
6+
node *go[C], *link;
7+
bool mark;
8+
} pool[MAXL], *rt;
9+
int sz;
10+
node* alloc() {
11+
memset(&pool[sz], 0, sizeof(pool[sz]));
12+
return &pool[sz++];
13+
}
14+
void init() {
15+
sz = 0;
16+
rt = alloc();
17+
}
18+
void ins(const char *s) {
19+
node *p = rt;
20+
for (int i = 0; s[i]; ++i) {
21+
int o = s[i] - 'a';
22+
if (!p->go[o]) p->go[o] = alloc();
23+
p = p->go[o];
24+
}
25+
p->mark = true;
26+
}
27+
void build() {
28+
std::queue<node*> queue;
29+
for (int o = 0; o < C; ++o) {
30+
if (rt->go[o]) {
31+
rt->go[o]->link = rt;
32+
queue.push(rt->go[o]);
33+
} else {
34+
rt->go[o] = rt;
35+
}
36+
}
37+
for (; !queue.empty(); queue.pop()) {
38+
node* u = queue.front();
39+
u->mark |= u->link->mark;
40+
for (int o = 0; o < C; ++o) {
41+
if (u->go[o]) {
42+
u->go[o]->link = u->link->go[o];
43+
queue.push(u->go[o]);
44+
} else {
45+
u->go[o] = u->link->go[o];
46+
}
47+
}
48+
}
49+
}
50+
bool find(const char *s) {
51+
node *p = rt;
52+
for (int i = 0; s[i]; ++i) {
53+
int o = s[i] - 'a';
54+
p = p->go[o];
55+
if (p->mark) return true;
56+
}
57+
return false;
58+
}
59+
};
60+
61+
struct AhoCorasickMap {
62+
static const int MAXL = 1e5;
63+
struct node {
64+
std::map<char, node*> go;
65+
node *link;
66+
bool mark;
67+
node* next(char o) {
68+
if (go.count(o)) return go[o];
69+
else if (link) return link->next(o);
70+
else return this;
71+
}
72+
} pool[MAXL], *rt;
73+
int sz;
74+
node* alloc() {
75+
pool[sz].go.clear();
76+
pool[sz].link = 0;
77+
pool[sz].mark = 0;
78+
return &pool[sz++];
79+
}
80+
void init() {
81+
sz = 0;
82+
rt = alloc();
83+
}
84+
void ins(const char *s) {
85+
node *p = rt;
86+
for (int i = 0; s[i]; ++i) {
87+
char o = s[i];
88+
if (!p->go.count(o)) p->go[o] = alloc();
89+
p = p->go[o];
90+
}
91+
p->mark = true;
92+
}
93+
void build() {
94+
std::queue<node*> queue;
95+
for (auto &x: rt->go) {
96+
x.second->link = rt;
97+
queue.push(x.second);
98+
}
99+
for (; !queue.empty(); queue.pop()) {
100+
node* u = queue.front();
101+
u->mark |= u->link->mark;
102+
for (auto &x: u->go) {
103+
x.second->link = u->link->next(x.first);
104+
queue.push(x.second);
105+
}
106+
}
107+
}
108+
bool find(const char *s) {
109+
node *p = rt;
110+
for (int i = 0; s[i]; ++i) {
111+
char o = s[i];
112+
p = p->next(o);
113+
if (p->mark) return true;
114+
}
115+
return false;
116+
}
117+
};

0 commit comments

Comments
 (0)