Pagini recente » Cod sursa (job #1198972) | Cod sursa (job #447006) | Cod sursa (job #1523894) | Cod sursa (job #2846978) | Cod sursa (job #2843030)
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
const int MAX_N = 100;
const int SIGMA = 26;
struct Trie {
int freq;
Trie* children[SIGMA];
Trie* failLink;
Trie() {
freq = 0;
for (int i = 0; i < SIGMA; i++) {
children[i] = NULL;
}
failLink = NULL;
}
};
Trie* pos[1 + MAX_N];
std::vector<Trie*> order;
Trie* insert(Trie* root, char* S) {
if (*S == '\0') {
return root;
} else {
if (root->children[S[0] - 'a'] == NULL) {
root->children[S[0] - 'a'] = new Trie();
}
return insert(root->children[S[0] - 'a'], S + 1);
}
}
void ahoCorasick(Trie* root) {
std::queue<Trie*> q;
q.push(root);
root->failLink = root;
while (!q.empty()) {
Trie* u = q.front();
order.push_back(u);
q.pop();
for (int i = 0; i < SIGMA; i++) {
if (u->children[i] != NULL) {
u->children[i]->failLink = u->failLink;
while (u->children[i]->failLink != root && u->children[i]->failLink->children[i] == NULL) {
u->children[i]->failLink = u->children[i]->failLink->failLink;
}
if (u->children[i]->failLink->children[i] != NULL && u != root) {
u->children[i]->failLink = u->children[i]->failLink->children[i];
}
q.push(u->children[i]);
}
}
}
}
void count(Trie* root, char* T) {
Trie* u = root;
for (int i = 0; T[i] != '\0'; i++) {
while (u != root && u->children[T[i] - 'a'] == NULL) {
u = u->failLink;
}
if (u->children[T[i] - 'a'] != NULL) {
u = u->children[T[i] - 'a'];
}
u->freq++;
}
}
void answer() {
std::reverse(order.begin(), order.end());
for (Trie* it : order) {
it->failLink->freq += it->freq;
}
}
int main() {
std::ifstream fin("ahocorasick.in");
std::ofstream fout("ahocorasick.out");
Trie root;
char* T = new char[1000000 + 1];
char* C = new char[100000 + 1];
int n;
fin >> T >> n;
for (int i = 1; i <= n; i++) {
fin >> C;
pos[i] = insert(&root, C);
}
ahoCorasick(&root);
count(&root, T);
answer();
for (int i = 1; i <= n; i++) {
fout << pos[i]->freq << "\n";
}
return 0;
}