Pagini recente » Cod sursa (job #1729742) | Cod sursa (job #1264766) | Cod sursa (job #1838136) | Cod sursa (job #2297091) | Cod sursa (job #2766945)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;
const int ALPHA_SZ = 26;
struct Aho{
Aho* children[ALPHA_SZ];
Aho* failLink;
vector<int> words;
int cnt;
Aho(){
cnt = 0;
failLink = nullptr;
words = {};
for(int i = 0; i < ALPHA_SZ; ++i)
children[i] = nullptr;
}
};
Aho* AHC = new Aho();
void insert(Aho* node, int pos, const int& id, const vector<string>& patterns){
if(pos == patterns[id].size()){
node->words.push_back(id);
return;
}
if(node->children[patterns[id][pos] - 'a'] == nullptr)
node->children[patterns[id][pos] - 'a'] = new Aho();
insert(node->children[patterns[id][pos] - 'a'], pos + 1, id, patterns);
}
void BFS(){
AHC->failLink = AHC;
queue<Aho*> Q;
for(int i = 0; i < ALPHA_SZ; ++i)
if(AHC->children[i] != nullptr){
AHC->children[i]->failLink = AHC;
Q.push(AHC->children[i]);
}
while(!Q.empty()){
Aho* curr = Q.front(); Q.pop();
for(int i = 0; i < ALPHA_SZ; ++i)
if(curr->children[i] != nullptr){
Aho* fail = curr->failLink;
while(fail != AHC && fail->children[i] == nullptr)
fail = fail->failLink;
if(fail->children[i] != nullptr && fail->children[i] != curr->children[i])
fail = fail->children[i];
curr->children[i]->failLink = fail;
Q.push(curr->children[i]);
}
}
}
vector<int> solve(const int& N, const string& text){
vector<int> freq(N);
Aho* head = AHC;
for(int i = 0; i < text.size(); ++i){
while(head != AHC && head->children[text[i] - 'a'] == nullptr)
head = head->failLink;
if(head->children[text[i] - 'a'] != nullptr)
head = head->children[text[i] - 'a'];
++head->cnt;
}
queue<Aho*> Q;
vector<Aho*> nodes;
Q.push(AHC);
while(!Q.empty()){
Aho* curr = Q.front(); Q.pop();
nodes.push_back(curr);
for(int i = 0; i < ALPHA_SZ; ++i)
if(curr->children[i] != nullptr)
Q.push(curr->children[i]);
}
reverse(nodes.begin(), nodes.end());
for(Aho* node : nodes){
for(auto id : node->words)
freq[id] += node->cnt;
node->failLink->cnt += node->cnt;
}
return freq;
}
int main()
{
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
cin.tie(nullptr)->sync_with_stdio(false);
string text; cin >> text;
int N; cin >> N;
vector<string> patterns(N);
for(int i = 0; i < N; ++i){
cin >> patterns[i];
insert(AHC, 0, i, patterns);
}
BFS();
vector<int> res = solve(N, text);
for(auto r : res)
cout << r << "\n";
cin.close();
cout.close();
return 0;
}