Pagini recente » Cod sursa (job #779559) | Cod sursa (job #2262554) | Cod sursa (job #782982) | Cod sursa (job #900270) | Cod sursa (job #2243813)
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<cstring>
using namespace std;
struct trie {
vector<int> words;
trie *next[27], *error;
int count;
trie () {
count = 0;
words.clear();
error = 0;
memset(next,0,sizeof(next));
}
};
trie *root = new trie();
int n, sol[105];
string a, w;
vector<trie *> bfs_order;
void insert(string w, int idx) {
trie *aux = root;
for (int i=0; i<w.length(); ++i) {
if (aux->next[w[i]-'a']==0) aux->next[w[i]-'a']=new trie();
aux = aux->next[w[i]-'a'];
}
aux->words.push_back(idx);
}
void build_error_links() {
bfs_order.clear();
bfs_order.push_back(root);
for (int i=0; i<bfs_order.size(); ++i)
for (int j=0; j<=26; ++j)
if (bfs_order[i]->next[j]!=0){
bfs_order.push_back(bfs_order[i]->next[j]);
trie *start = bfs_order[i]->error;
while (start!=root && start->next[j]==0) start = start->error;
if (bfs_order[i]!=root && start->next[j]!=0) bfs_order[i]->next[j]->error = start->next[j];
else bfs_order[i]->next[j]->error = root;
}
}
void propagate_counts(trie *aux) {
for (int i=bfs_order.size()-1; i>=0; --i) {
aux = bfs_order[i];
aux->error->count += aux->count;
for (int j=0; j<aux->words.size(); ++j)
sol[aux->words[j]]=aux->count;
}
}
int main(void) {
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
cin>>a>>n;
for (int i=1; i<=n; ++i) {
cin>>w;
insert(w, i);
}
root->error = root;
build_error_links();
trie *aux = root;
for (int i=0; i<a.length(); ++i) {
while (aux->next[a[i]-'a']==0 && aux!=root) aux = aux->error;
if (aux->next[a[i]-'a']!=0) aux = aux->next[a[i]-'a'];
++aux->count;
}
propagate_counts(root);
for (int i=1; i<=n; ++i) cout<<sol[i]<<"\n";
return 0;
}