Pagini recente » Istoria paginii utilizator/mihaibugeak | Cod sursa (job #1777534) | Cod sursa (job #1355044) | Cod sursa (job #2079239) | Cod sursa (job #1232893)
#include <fstream>
//#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <queue>
#include <cassert>
using namespace std;
struct state{
vector<int> word;
int fail;
int total;
int grad;
int father;
char letter;
int transitions[26];
state(int father=0,char letter=0): fail(0), total(0), grad(0), father(father), letter(letter) {
memset(transitions, 0, sizeof(transitions));
}
};
int frecv[105];
class automaton{
public:
vector<state> states;
inline int new_automaton_state(int father=0,char letter=0){
states.push_back(state(father,letter));
return (states.size()-1);
}
public:
automaton(){
new_automaton_state();
}
inline void add_word(const string &s,int index){
int k=0;
for(int i=0;i<s.size();++i){
if(!states[k].transitions[s[i]-'a']){
int aux=new_automaton_state(k,s[i]-'a');
states[k].transitions[s[i]-'a']=aux;
}
k=states[k].transitions[s[i]-'a'];
}
states[k].word.push_back(index);
}
inline void build_fails(){
queue<int> coada;
coada.push(0);
int k;
int y;
while(!coada.empty()){
y=coada.front();
coada.pop();
if(states[y].father){
k=states[states[y].father].fail;
while(k && !states[k].transitions[states[y].letter])
k=states[k].fail;
if(states[k].transitions[states[y].letter])
k=states[k].transitions[states[y].letter];
states[y].fail=k;
states[states[y].fail].grad++;
}
for(int i=0;i<26;i++)
if(states[y].transitions[i])
coada.push(states[y].transitions[i]);
}
}
inline void run_automaton(const string &s){
int k=0;
int p;
vector<int>::iterator it;
long long steps=0;
for(int i=0;i<s.size();++i){
while(k && !states[k].transitions[s[i]-'a'])
k=states[k].fail;
if(states[k].transitions[s[i]-'a'])
k=states[k].transitions[s[i]-'a'];
states[k].total++;
}
//cerr<<"deci "<<steps<<endl;
}
inline void calc_final(){
queue<int> coada;
bool ok;
int j;
for(int i=0;i<states.size();i++){
ok=true;
for(j=0;j<26;j++)
if(states[i].transitions[j]){
ok=false;
break;
}
if(ok)
coada.push(i);
}
int y;
while(!coada.empty()){
y=coada.front();
coada.pop();
if(states[y].fail){
states[states[y].fail].total+=states[y].total;
states[states[y].fail].grad--;
}
if(states[y].father && !states[states[y].father].grad)
coada.push(states[y].father);
}
}
};
int main()
{
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
ios_base::sync_with_stdio(false);
automaton x;
string sir;
getline(cin,sir);
string curent;
int n=0;
cin>>n;
//cerr<<"gata0"<<endl;
for(int i=1;i<=n;i++){
cin>>curent;
x.add_word(curent,i);
//cerr<<"gata1 "<<i<<endl;
}
//cerr<<"gata2"<<endl;
x.build_fails();
//cerr<<"gata3"<<endl;
x.run_automaton(sir);
x.calc_final();
vector<int>::iterator it;
for(int i=0;i<x.states.size();i++){
for(it=x.states[i].word.begin();it!=x.states[i].word.end();it++)
frecv[*it]+=x.states[i].total;
}
//cerr<<"gata4"<<endl;
for(int i=1;i<=n;i++)
cout<<frecv[i]<<'\n';
//cerr<<"gata5"<<endl;
cin.close();
cout.close();
return 0;
}