Skip to content

Commit a134c1b

Browse files
committed
Aho-Corasick
1 parent 2f63329 commit a134c1b

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ AtCoder解説放送ライブラリ集
3737
|名前|コード|説明|
3838
|:--|:--|:--|
3939
|KMP|[mp.cpp](mp.cpp)|文字列検索アルゴリズム(正確にはMP)|
40+
|Z|[z.cpp](z.cpp)|Z-algorithm|
41+
|Aho-Corasick|[aho.cpp](aho.cpp)|文字列集合へのマッチを検出する|
4042

4143
### 幾何
4244
|名前|コード|説明|

aho.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Aho-Corasick
2+
// https://youtu.be/BYoRvdgI5EU?t=9633
3+
struct Aho {
4+
using MP = unordered_map<char,int>;
5+
vector<MP> to;
6+
vector<int> cnt, fail;
7+
Aho(): to(1), cnt(1) {}
8+
int add(const string& s) {
9+
int v = 0;
10+
for (char c : s) {
11+
if (!to[v].count(c)) {
12+
to[v][c] = to.size();
13+
to.push_back(MP());
14+
cnt.push_back(0);
15+
}
16+
v = to[v][c];
17+
}
18+
cnt[v]++;
19+
return v;
20+
}
21+
void init() {
22+
fail = vector<int>(to.size(), -1);
23+
queue<int> q;
24+
q.push(0);
25+
while (!q.empty()) {
26+
int v = q.front(); q.pop();
27+
for (auto [c,u] : to[v]) {
28+
fail[u] = (*this)(fail[v],c);
29+
cnt[u] += cnt[fail[u]];
30+
q.push(u);
31+
}
32+
}
33+
}
34+
int operator()(int v, char c) const {
35+
while (v != -1) {
36+
auto it = to[v].find(c);
37+
if (it != to[v].end()) return it->second;
38+
v = fail[v];
39+
}
40+
return 0;
41+
}
42+
int operator[](int v) const { return cnt[v];}
43+
};

0 commit comments

Comments
 (0)