Pagini recente » Atasamentele paginii Cel mai cartof | Diferente pentru utilizator/dinugafton intre reviziile 2 si 3 | Profil CristianD | problemiada_10 | Cod sursa (job #804545)
Cod sursa(job #804545)
#include <fstream>
#include <string>
#include <queue>
#include <iostream>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
int const ALF_SIZE=26;
int aparitii[11000];
class node;
vector < node* > ordbf;
class node{
bool final;
int appereances;
vector<int> wordnr;
node *link[ALF_SIZE];
node *pref;
node *nextDictWord;
public:
node(){
int i;
for(i=0;i<ALF_SIZE;++i){
this->link[i]=NULL;
}
this->final=false;
this->nextDictWord=NULL;
this->appereances=0;
}
node* linknode(char x){
if(link[x-'a']){
return link[x-'a'];
}
link[x-'a']=new node();
return link[x-'a'];
}
bool setfinal(int x){
final=true;
wordnr.push_back(x);
return true;
}
bool isfinal(){
return final;
}
bool ahoCorasick(){
int i;
queue<node *> coada;
for(i=0;i<ALF_SIZE;++i){
if(link[i]){
coada.push(link[i]);
ordbf.push_back(link[i]);
link[i]->pref=this;
}
}
node *tata,*fiu,*aux;
while(!coada.empty()){
tata=coada.front();
coada.pop();
for(i=0;i<ALF_SIZE;++i){
if(tata->link[i]){
fiu=tata->link[i];
aux=tata->pref;
coada.push(fiu);
ordbf.push_back(fiu);
while(aux!=NULL){
if(aux->link[i]){
fiu->pref=aux->link[i];
break;
}
aux=aux->pref;
}
if(aux==NULL){
fiu->pref=this;
}
aux=fiu->pref;
while(aux!=NULL){
if(aux->isfinal()){
fiu->nextDictWord=aux;
break;
}
aux=aux->pref;
}
}
}
}
return true;
}
void parse(string s){
node * currentnode=this;
string::iterator it;
for(it=s.begin();it<s.end();++it){
while(currentnode->link[*it-'a']==NULL && currentnode!=this){
currentnode=currentnode->pref;
}
if(currentnode->link[*it-'a']){
currentnode=currentnode->link[*it-'a'];
currentnode->appereances++;
}
}
}
void update_appereances(){
int i;
for(i=ordbf.size()-1;i>=0;--i){
if(ordbf[i]->nextDictWord!=this && ordbf[i]->nextDictWord){
ordbf[i]->nextDictWord->appereances+=ordbf[i]->appereances;
}
if(!ordbf[i]->isfinal())
continue;
for(int j=0;j<ordbf[i]->wordnr.size();++j){
aparitii[ordbf[i]->wordnr[j]]=ordbf[i]->appereances;
}
}
}
};
class automata{
node *root;
public:
automata(){
root=new node();
}
bool add(string s,int wordnr){
node *currentnode=root;
root->setfinal(0);
string:: iterator it;
for(it=s.begin();it<s.end();++it){
currentnode=currentnode->linknode(*it);
}
currentnode->setfinal(wordnr);
}
bool constructautomata(){
return root->ahoCorasick();
}
void search(string s){
root->parse(s);
root->update_appereances();
}
};
int main(){
automata AhoCorasick;
string sir,cuvant;
int i;
int nrcuvinte;
in>>sir;
in>>nrcuvinte;
for(i=1;i<=nrcuvinte;++i){
in>>cuvant;
AhoCorasick.add(cuvant,i);
}
AhoCorasick.constructautomata();
AhoCorasick.search(sir);
for(i=1;i<=nrcuvinte;++i){
out<<aparitii[i]<<"\n";
}
return 0;
}