Mai intai trebuie sa te autentifici.
Cod sursa(job #804519)
Utilizator | Data | 29 octombrie 2012 21:50:15 | |
---|---|---|---|
Problema | Aho-Corasick | Scor | 95 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 3.99 kb |
#include <fstream>
#include <string>
#include <queue>
#include <iostream>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
int const ALF_SIZE=35;
string cuvinte[11000];
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->pref=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 df(){
int i;
/*for(i=0;i<ordbf.size();i++){
if(!ordbf[i]->isfinal()){
continue;
}
for(int j=0;j<ordbf[i]->wordnr.size();++j){
out<<cuvinte[ordbf[i]->wordnr[j]]<<":"<<ordbf[i]->appereances<<"\n";
}
}*/
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]->nextDictWord->isfinal()){
for(int j=0;j<ordbf[i]->wordnr.size();++j){
aparitii[ordbf[i]->nextDictWord->wordnr[j]]+=ordbf[i]->appereances;
}
}*/
}
for(int j=0;j<ordbf[i]->wordnr.size();++j){
aparitii[ordbf[i]->wordnr[j]]=ordbf[i]->appereances;
//out<<cuvinte[ordbf[i]->wordnr[j]]<<":"<<ordbf[i]->appereances<<"\n";
}
}
/*if(ordbf[i]->pref){
ordbf[i]->pref->appereances+=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->df();
}
};
int main(){
automata AhoCorasick;
string sir,cuvant;
int i;
int nrcuvinte;
in>>sir;
in>>nrcuvinte;
for(i=1;i<=nrcuvinte;++i){
in>>cuvant;
cuvinte[i]=cuvant;
AhoCorasick.add(cuvant,i);
}
AhoCorasick.constructautomata();
AhoCorasick.search(sir);
for(i=1;i<=nrcuvinte;++i){
out<<aparitii[i]<<"\n";
}
return 0;
}