Pagini recente » Cod sursa (job #946850) | Cod sursa (job #725680) | Cod sursa (job #816470) | Cod sursa (job #555058) | Cod sursa (job #1267549)
#include <vector>
#include <fstream>
#include <cstdio>
#include <queue>
#include <string>
#include <climits>
#include <iostream>
#include <cassert>
#define pb push_back
using namespace std;
class Node {
public:
vector <Node*> step;
vector <int> words;
Node *fail;
int endHere;
Node() {
fail = 0;
endHere = 0;
step.resize(26, 0);
}
void insert(int pos, int lg, string &text, int id) {
if (pos == lg) {
words.pb(id);
return;
}
int to = text[pos] - 'a';
if (step[to] == 0) {
step[to] = new Node();
}
step[to]->insert(pos + 1, lg, text, id);
}
};
int N;
vector <Node*> que;
Node *rootTrie;
string plaintext;
vector <int> nrWords;
void breadth_first_search(Node *root);
void rev_breadth_first_search();
void solve();
int main() {
#ifdef INFOARENA
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
#else
freopen("input", "r", stdin);
#endif
int i;
string word;
ios_base::sync_with_stdio(false);
rootTrie = new Node();
cin >> plaintext;
cin >> N;
nrWords.resize(N);
for (i = 0; i < N; ++i) {
cin >> word;
rootTrie->insert(0, (int) word.length(), word, i);
}
breadth_first_search(rootTrie);
solve();
rev_breadth_first_search();
for (i = 0; i < N; ++i) {
printf("%d\n", nrWords[i]);
}
return 0;
}
void solve() {
int lgText, i, to;
Node *node = rootTrie;
lgText = (int) plaintext.length();
for (i = 0; i < lgText; ++i) {
to = plaintext[i] - 'a';
assert(node != 0);
for (;node != rootTrie && node->step[to] == 0; node = node->fail);
if (node->step[to] != 0) {
node = node->step[to];
assert(node != 0);
++node->endHere;
}
}
}
void rev_breadth_first_search() {
int i, j;
Node *node;
for (i = (int) que.size() - 1; i; --i) {
node = que[i];
node->fail->endHere += node->endHere;
for (j = (int) node->words.size() - 1; j >= 0; --j) {
nrWords[node->words[j]] += node->endHere;
}
}
}
void breadth_first_search(Node *root) {
int alpha, omega, to;
Node *toFail, *node;
root->fail = root;
alpha = omega = 1;
que.pb(0);
que.pb(root);
while(alpha <= omega) {
node = que[alpha];
++alpha;
for (to = 0; to < 26; ++to) {
if (node->step[to] != 0) {
for (toFail = node->fail; toFail != root && toFail->step[to] == 0; toFail = toFail->fail);
if (toFail->step[to] != 0 && toFail->step[to] != node->step[to]) {
node->step[to]->fail = toFail->step[to];
}
else {
node->step[to]->fail = root;
}
++omega;
que.pb(node->step[to]);
}
}
}
}