Pagini recente » Cod sursa (job #567757) | Cod sursa (job #2020961) | Cod sursa (job #1851351) | Cod sursa (job #2329096) | Cod sursa (job #2487424)
#include <algorithm>
#include <fstream>
#include <queue>
#include <string.h>
#include <vector>
std::ifstream fin("ahocorasick.in");
std::ofstream fout("ahocorasick.out");
const int SIGMA = 26;
const int MAX_N = 100;
struct Trie {
int nrf;
int nrc;
Trie* children[SIGMA];
Trie* fail;
int nr;
Trie() {
nrf = 0;
nrc = 0;
for (int i = 0; i < SIGMA; i++)
children[i] = NULL;
fail = NULL;
}
};
int numNodes;
Trie* nodes[5 + MAX_N];
void insert(Trie* nod, char* s) {
if (s[0] == '\0') {
nod->nrc++;
nodes[++numNodes] = nod;
} else {
if (nod->children[s[0] - 'a'] == NULL) {
nod->nrf++;
nod->children[s[0] - 'a'] = new Trie;
}
insert(nod->children[s[0] - 'a'], s + 1);
}
}
const int MAX_SIZE = 1000000;
const int MAX_D = 1000;
char T[5 + MAX_SIZE];
std::vector<Trie*> bfs;
void antiBFS() {
std::reverse(bfs.begin(), bfs.end());
for (Trie *nod : bfs)
nod->fail->nr += nod->nr;
}
int main() {
fin >> T;
Trie *root = new Trie;
int n;
fin >> n;
for (int i = 1; i <= n; i++) {
char s[5 + MAX_D];
fin >> s;
insert(root, s);
}
std::queue<Trie*> q;
root->fail = NULL;
for (int i = 0; i < SIGMA; i++) {
if (root->children[i] != NULL) {
root->children[i]->fail = root;
q.push(root->children[i]);
}
}
while (!q.empty()) {
Trie* parent = q.front();
q.pop();
for (int i = 0; i < SIGMA; i++) {
if (parent->children[i] != NULL) {
Trie* child = parent->children[i];
q.push(child);
bfs.push_back(child);
Trie* aux = parent->fail;
while (aux != root && aux->children[i] == NULL)
aux = aux->fail;
if (aux->children[i] != NULL)
child->fail = aux->children[i];
else
child->fail = root;
}
}
}
int sizeT = strlen(T);
Trie* current = root;
for (int i = 0; i < sizeT; i++) {
while (current != root && current->children[T[i] - 'a'] == NULL)
current = current->fail;
if (current->children[T[i] - 'a'] != NULL)
current = current->children[T[i] - 'a'];
else
current = root;
if (current != root)
current->nr++;
}
antiBFS();
for (int i = 1; i <= n; i++)
fout << nodes[i]->nr << '\n';
return 0;
}