Pagini recente » Cod sursa (job #980540) | Cod sursa (job #1630928) | Cod sursa (job #1068768) | Cod sursa (job #629566) | Cod sursa (job #3332341)
#include <bits/stdc++.h>
using namespace std;
struct Node {
array<int, 26> next; // transitions
int fail; // failure link
vector<int> out; // indices of words ending here
Node() {
next.fill(-1);
fail = 0;
}
};
class AhoCorasick {
vector<Node> trie;
public:
AhoCorasick() { trie.emplace_back(); }
void insert(const string &word, int index) {
int node = 0;
for (char ch : word) {
int c = ch - 'a';
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size();
trie.emplace_back();
}
node = trie[node].next[c];
}
trie[node].out.push_back(index);
}
void build() {
queue<int> q;
// initialize root transitions
for (int c = 0; c < 26; c++) {
int nxt = trie[0].next[c];
if (nxt != -1) {
trie[nxt].fail = 0;
q.push(nxt);
} else {
trie[0].next[c] = 0;
}
}
// BFS
while (!q.empty()) {
int u = q.front(); q.pop();
for (int c = 0; c < 26; c++) {
int v = trie[u].next[c];
if (v != -1) {
trie[v].fail = trie[trie[u].fail].next[c];
// merge outputs
trie[v].out.insert(trie[v].out.end(),
trie[trie[v].fail].out.begin(),
trie[trie[v].fail].out.end());
q.push(v);
} else {
trie[u].next[c] = trie[trie[u].fail].next[c];
}
}
}
}
vector<int> search(const string &text, int nWords) {
vector<int> result(nWords, 0);
int node = 0;
for (char ch : text) {
int c = ch - 'a';
node = trie[node].next[c];
for (int idx : trie[node].out) {
result[idx]++;
}
}
return result;
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
string A;
int n;
cin >> A >> n;
vector<string> words(n);
for (int i = 0; i < n; i++) cin >> words[i];
AhoCorasick ac;
for (int i = 0; i < n; i++) ac.insert(words[i], i);
ac.build();
vector<int> ans = ac.search(A, n);
for (int x : ans) cout << x << "\n";
}