Pagini recente » Cod sursa (job #1464852) | Cod sursa (job #2082798) | Cod sursa (job #1578433) | Cod sursa (job #2472632) | Cod sursa (job #1229350)
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#if __cplusplus > 199711L
#include <unordered_map>
#include <unordered_set>
#endif
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdlib>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
const int ALPHABET_SIZE = 26, LMAX = 1000010, LWORDMAX = 10010;
struct AhoCorasickAutomaton {
int matches;
vector<int> finish;
AhoCorasickAutomaton *child[ALPHABET_SIZE], *fail;
AhoCorasickAutomaton() {
matches = 0;
fail = 0;
memset(child, 0, sizeof(child));
}
} *AC;
vector<AhoCorasickAutomaton *> Q;
int N, start, finish;
int res[LWORDMAX];
char str[LMAX], word[LWORDMAX];
void insert_word(AhoCorasickAutomaton *node, char *str, int pos) {
if (*str == 0) {
node->finish.push_back(pos);
return;
}
if (node->child[*str - 'a'] == 0) node->child[*str - 'a'] = new AhoCorasickAutomaton;
insert_word(node->child[*str - 'a'], str + 1, pos);
}
void BF() {
AhoCorasickAutomaton *fail;
AC->fail = AC;
Q.push_back(AC);
while(start <= finish) {
AhoCorasickAutomaton *node = Q[start++];
for (int i = 0; i < ALPHABET_SIZE; ++i) {
if (node->child[i] == 0) continue;
for (fail = node->fail; fail != AC && fail->child[i] == 0; fail = fail->fail);
if (fail->child[i] != 0 && fail->child[i] != node->child[i]) fail = fail->child[i];
node->child[i]->fail = fail;
Q.push_back(node->child[i]);
++finish;
}
}
AC->fail = 0;
}
void ABF() {
while(finish >= 0) {
AhoCorasickAutomaton *node = Q[finish--];
if (node->fail != 0) node->fail->matches += node->matches;
for (int i = 0; i < (int)node->finish.size(); ++i)
res[node->finish[i]] = node->matches;
}
}
int main() {
int i;
in.getline(str, LMAX);
in >> N;
in.getline(word, LWORDMAX);
AC = new AhoCorasickAutomaton;
for (i = 1; i <= N; ++i) {
in.getline(word, LWORDMAX);
insert_word(AC, word, i);
}
BF();
AhoCorasickAutomaton *_AC = AC;
for (i = 0; str[i]; ++i) {
for ( ; _AC != AC && _AC->child[str[i] - 'a'] == 0; _AC = _AC->fail);
if (_AC->child[str[i] - 'a'] != 0) _AC = _AC->child[str[i] - 'a'];
++_AC->matches;
}
ABF();
for (i = 1; i <= N; ++i) out << res[i] << '\n';
in.close(), out.close();
return 0;
}