Pagini recente » Cod sursa (job #1055358) | Cod sursa (job #227094) | Cod sursa (job #1257736) | Cod sursa (job #1062786) | Cod sursa (job #2595004)
#include <fstream>
#include <vector>
#include <cctype>
#include <cstring>
#define AMAXLENGTH 1000005
#define DICTMAXLENGTH 10005
#define NMAX 105
#define DALF 26
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
struct ac{
vector<int> cuv; //indicii cuvintelor care se termina in nodul curent
ac *copii[DALF];
ac *fail;
int nrpotriviri;
ac(){
nrpotriviri = 0;
fail = NULL;
memset(copii, 0, sizeof(copii));
}
}*r, *q[DALF*DALF];
int ic, sc; // pt a parcurge q
int n;
int fin[DICTMAXLENGTH];
char a[AMAXLENGTH];
char c[DICTMAXLENGTH];
void adaug(ac *nod, char *cuvant, int ind){ // adaugarea ca si in trie
if(!isalpha(*cuvant)){
nod->cuv.push_back(ind);
return;
}
if(!nod->copii[*cuvant - 'a'])
nod->copii[*cuvant - 'a'] = new ac();
adaug(nod->copii[*cuvant - 'a'], cuvant+1,ind);
}
void citire(){
f.getline(a, AMAXLENGTH);
f>>n;
f.get();
for(int i=1; i<=n; i++){
f.getline(c, DICTMAXLENGTH);
adaug(r, c, i);
}
}
void bfs(ac *t){
ac *cautfail;
t->fail = t;
ic = sc = 1;
for(q[ic] = t; ic<=sc; ic++){
ac *fr = q[ic];
for(int i=0; i<DALF; i++)
if(fr->copii[i] != NULL){ // nodul caruia ii cautam failul
for(cautfail = fr->fail; cautfail!=t && cautfail->copii[i]==NULL; cautfail = cautfail->fail);
if(cautfail->copii[i]!=NULL && cautfail->copii[i] != fr->copii[i])
cautfail = cautfail->copii[i];
fr->copii[i]->fail = cautfail;
q[++sc] = fr->copii[i];
}
}
t->fail = NULL;
}
void antibfs(ac *t){
// parcurgem nodurile in ordinea invers a bfs-ului
// daca avem caa, putem adauga si la fail (aka cel mai lung sufix) numarul aparitiilor
for(int i=sc; i>0; i--){
ac *fr = q[i];
if(fr->fail!=NULL)
fr->fail->nrpotriviri += fr->nrpotriviri;
for(int j=0; j<fr->cuv.size(); j++)
fin[fr->cuv[j]] = fr->nrpotriviri;
}
}
void legaturi_sufix(){
r->fail = r;
bfs(r);
}
void solve(){
ac *p = r;
int lungime = strlen(a);
for(int i=0; i<lungime; i++){
int urm = a[i]-'a';
for(;p->copii[urm]==NULL && p!=r; p=p->fail);
if(p->copii[urm]!=NULL)
p=p->copii[urm];
p->nrpotriviri++;
}
}
int main()
{
r = new ac();
citire();
legaturi_sufix();
solve();
antibfs(r);
for(int i=1; i<=n; i++)
g<<fin[i]<<'\n';
return 0;
}