Pagini recente » Cod sursa (job #1699035) | Cod sursa (job #263853) | Cod sursa (job #320095) | Cod sursa (job #772883) | Cod sursa (job #2243466)
#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();
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(trie *aux) {
for (int i=0; i<=26; ++i)
if (aux->next[i]!=0) {
trie *start = aux->error;
while (start!=root && start->next[i]==0) start = start->error;
if (aux!=root && start->next[i]!=0) aux->next[i]->error = start->next[i];
else aux->next[i]->error = root;
build_error_links(aux->next[i]);
}
}
void propagate_counts(trie *aux) {
bfs_order.clear();
bfs_order.push_back(aux);
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]);
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(root);
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;
}