Pagini recente » Cod sursa (job #3276121) | Cod sursa (job #2609129) | Cod sursa (job #258838) | Cod sursa (job #2923508) | Cod sursa (job #1772838)
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
#define ALPHA_LEN 26
std::ifstream in("ahocorasick.in");
std::ofstream out("ahocorasick.out");
class Trie {
public:
Trie* next[ALPHA_LEN];
std::vector<int> indexes;
Trie* fail;
int nr;
Trie() {
for (int i = 0; i < ALPHA_LEN; i++)
this->next[i] = NULL;
nr = 0;
}
void insert(std::string &s, int pos, int index) {
if (pos == s.size()) {
this->indexes.push_back(index);
return;
}
int i = s[pos] - 'a';
if (this->next[i] == NULL) {
this->next[i] = new Trie();
}
this->next[i]->insert(s, pos + 1, index);
}
};
std::vector<Trie*> Q;
void BFS(Trie* root) {
root->fail = root;
Q.push_back(root);
int index = 0;
while (index < Q.size()) {
Trie* node = Q[index];
for (int i = 0; i < ALPHA_LEN; i++) {
if (node->next[i] != NULL) {
Trie* dolar = node->fail;
while (dolar != root && dolar->next[i] == NULL)
dolar = dolar->fail;
if (dolar->next[i] != NULL && dolar != node)
dolar = dolar->next[i];
node->next[i]->fail = dolar;
Q.push_back(node->next[i]);
}
}
index++;
}
root->fail = NULL;
}
void anti_BFS(Trie *T, std::vector<int> &result) {
for (int i = Q.size() - 1; i >= 0; i--) {
Trie* node = Q[i];
for (const auto &ind : node->indexes)
result[ind] = node->nr;
if (node->fail != NULL) {
node->fail->nr += node->nr;
}
}
}
int main() {
std::string text;
in >> text;
int n;
in >> n;
Trie *T = new Trie();
for (int i = 0; i < n; i++) {
std::string word;
in >> word;
T->insert(word, 0, i);
}
BFS(T);
Trie *aux = T;
for (int i = 0; i < text.size(); i++) {
int pos = text[i] - 'a';
while (aux != T && aux->next[pos] == NULL) aux = aux->fail;
if (aux->next[pos] != NULL) aux = aux->next[pos];
aux->nr++;
}
std::vector<int> result(n);
anti_BFS(T, result);
for (const auto &el : result) {
out << el << "\n";
}
}