The Aho-Corasick Automaton is a data structure that maintains a set of strings in by maintaining a deterministic finite automaton that accepts and only accepts strings containing a string from as a suffix.
Specifically, let be the set of the prefixes of the strings in , and let
and let be a function in satisfying
Lemma
Let , then applying the lemma yields that is a deterministic finite automaton that accepts and only accepts strings containing a string from as a suffix.
This costs a space of .
Build
Build builds an Aho-Corasick Automaton for in time and space.
Algorithm
Lemma
Let
Then
Lemma
- Build a Trie for .
- For each prefix in increasing order of length, apply the lemmas to find the and for .
This algorithm solves the problem in time and space.
void build(int n, const std::vector<std::string> &s) {
next.assign(2, {});
next[0].fill(1);
f.assign(2, false);
for (int i = 0; i < n; i++) {
int o = 1;
for (char c : s[i]) {
if (!next[o][c]) {
next[o][c] = next.size();
next.emplace_back();
f.push_back(false);
}
o = next[o][c];
}
f[o] = true;
}
std::vector fail(next.size(), 0);
std::queue<int> q;
q.push(1);
while (!q.empty()) {
int o = q.front();
q.pop();
f[o] = f[o] || f[fail[o]];
for (char c : alphabet) {
if (next[o][c]) {
fail[next[o][c]] = next[fail[o]][c];
q.push(next[o][c]);
} else {
next[o][c] = next[fail[o]][c];
}
}
}
}Find
Find checks if in time and space.
Algorithm
Running on yields an algorithm that solves the problem in time and space.
bool find(const std::string &s) {
int o = 1;
for (char c : s) {
o = next[o][c];
}
return f[o];
}