Pagini recente » Cod sursa (job #1112249) | Cod sursa (job #1194051) | Cod sursa (job #488111) | Cod sursa (job #1875757) | Cod sursa (job #2717255)
#include <fstream>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
const int SIGMA = 26;
struct Node {
Node* children[SIGMA];
Node* failLink;
vector <int> wordList;
int cnt;
Node() {
for(int i = 0; i < SIGMA; i++) {
children[i] = NULL;
}
failLink = NULL;
cnt = 0;
}
};
Node *aho = new Node;
string text, s;
int N, freq[100 + 2];
void Insert(Node *node, int index, int wordId) {
if(index == (int)s.size()) {
node->wordList.push_back(wordId);
return;
} else {
if(node-> children[s[index] - 'a'] == NULL)
node-> children[s[index] - 'a'] = new Node;
Insert(node-> children[s[index] - 'a'], index + 1, wordId);
}
}
void ComputeAhoLinks() {
aho-> failLink = aho;
queue <Node*> Q;
for(int i = 0; i < SIGMA; i++) {
if(aho-> children[i] != NULL) {
aho-> children[i]-> failLink = aho;
Q.push(aho-> children[i]);
}
}
while(!Q.empty()) {
Node* node = Q.front();
Q.pop();
for(int i = 0; i < SIGMA; i++)
{
if(node->children[i] != NULL)
{
Node *failNode = node-> failLink;
while(failNode != aho && failNode-> children[i] == NULL) {
failNode = failNode-> failLink;
}
if(failNode-> children[i] != NULL && failNode-> children[i] != node-> children[i]) {
failNode = failNode-> children[i];
}
node->children[i]->failLink = failNode;
Q.push(node-> children[i]);
}
}
}
}
void Solve() {
Node *node = aho;
for(int i = 0; i < (int)text.size(); i++) {
while(node != aho && node-> children[text[i] - 'a'] == NULL) {
node = node-> failLink;
}
if(node-> children[text[i] - 'a'] != NULL) {
node = node-> children[text[i] - 'a'];
}
node-> cnt++;
}
queue <Node*> Q;
vector <Node*> antibfs;
Q.push(aho);
while(!Q.empty()) {
Node *node = Q.front();
Q.pop();
antibfs.push_back(node);
for(int i = 0; i < SIGMA; i++) {
if(node-> children[i] != NULL) {
Q.push(node-> children[i]);
}
}
}
reverse(antibfs.begin(), antibfs.end());
for(Node* node : antibfs) {
for(int wordId : node-> wordList) {
freq[wordId] += node-> cnt;
}
node->failLink->cnt += node->cnt;
}
for(int i = 1; i <= N; i++) {
cout << freq[i] << '\n';
}
}
int main() {
cin >> text;
cin >> N;
for(int i = 1; i <= N; i++) {
cin >> s;
Insert(aho, 0, i);
}
ComputeAhoLinks();
Solve();
return 0;
}