Pagini recente » Cod sursa (job #3172591) | Cod sursa (job #2474437) | Cod sursa (job #2642997) | Cod sursa (job #1488123) | Cod sursa (job #3124806)
// Source: https://drive.google.com/file/d/1puSAKcZT_Y3fz8MmYGOaa-QRJuyX1TB-gXO-Fl9dbE7L9sq2G-IAKKP8u0Fg/view
#include <bits/stdc++.h>
using namespace std;
const int ALPHABET_SIZE = 26;
struct Aho {
Aho *children[ALPHABET_SIZE];
Aho *failure;
int cnt;
Aho() {
cnt = 0;
failure = nullptr;
for (int i = 0; i < ALPHABET_SIZE; ++i)
children[i] = nullptr;
}
virtual ~Aho() {
}
};
Aho *AHC = new Aho();
vector<Aho *> terminals;
// construct Trie <-> Keyword tree construction
// word_id - index of word in vector<string>& w
// pos - ch. position in w[word_id]
void insert(Aho *node, int pos, const int &word_id, const vector<string> &w) {
if (pos == w[word_id].size()) {
terminals.emplace_back(node);
return;
}
const string &word = w[word_id];
if (node->children[word[pos] - 'a'] == nullptr)
node->children[word[pos] - 'a'] = new Aho();
insert(node->children[word[pos] - 'a'], pos + 1, word_id, w);
}
void BFS() {
AHC->failure = AHC;
queue<Aho *> Q;
// All nodes 's' of depth 1 have "failure link" back to root
for (int i = 0; i < ALPHABET_SIZE; ++i)
if (AHC->children[i]) {
AHC->children[i]->failure = AHC;
Q.push(AHC->children[i]);
}
while (!Q.empty()) {
Aho *curr = Q.front();
Q.pop();
for (int i = 0; i < ALPHABET_SIZE; ++i)
if (curr->children[i]) {
Aho *fail = curr->failure;
while (fail != AHC && fail->children[i] == nullptr)
fail = fail->failure;
if (fail->children[i] && fail->children[i] != curr->children[i])
fail = fail->children[i];
curr->children[i]->failure = fail;
Q.push(curr->children[i]);
}
}
}
void scanText(const int &K, const string &text) {
Aho *head = AHC;
for (const auto& ch: text) {
while (head != AHC && head->children[ch - 'a'] == nullptr)
head = head->failure;
if (head->children[ch - 'a'])
head = head->children[ch - 'a'];
head->cnt ++;
}
queue<Aho *> Q;
stack<Aho *> st;
Q.push(AHC);
while (!Q.empty()) {
Aho *curr = Q.front();
Q.pop();
st.push(curr);
for (int i = 0; i < ALPHABET_SIZE; ++i)
if (curr->children[i])
Q.push(curr->children[i]);
}
while (!st.empty()){
const Aho* node = st.top();
st.pop();
node->failure->cnt += node->cnt;
}
for (const Aho* node: terminals)
cout << node->cnt << '\n';
}
string text;
int K;
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
cin >> text;
cin >> K;
vector<string> w(K);
for (int i = 0; i < K; ++i) {
cin >> w[i];
insert(AHC, 0, i, w);
}
BFS();
scanText(K, text);
return 0;
}