Pagini recente » Cod sursa (job #962150) | Cod sursa (job #358698) | Cod sursa (job #270031) | Cod sursa (job #3263379) | Cod sursa (job #748914)
Cod sursa(job #748914)
#include<fstream>
#include<cstring>
#include<vector>
#include<cmath>
#define ch *c-'a'
using namespace std;
int n,lvlmax;
char A[1000100],cuv[110][10100];
struct Trie
{
int nr,c;
Trie *fiu[26],*back,*tata;
Trie(Trie *nod)
{
nr=0;
c=0;
tata=nod;
memset(fiu,0,sizeof(fiu));
back=NULL;
}
};
Trie *T;
vector <Trie*> nivel[26];
inline void Insert(Trie *nod,char *c,int lvl)
{
if(*c==0)
return;
if(nod->fiu[ch]==NULL)
{
nod->fiu[ch]=new Trie(nod);
nod->fiu[ch]->c=ch;
nivel[lvl+1].push_back(nod->fiu[ch]);
lvlmax=max(lvlmax,lvl+1);
}
Insert(nod->fiu[ch],c+1,lvl+1);
}
inline void Citire()
{
int i;
ifstream fin("ahocorasick.in");
fin>>A;
fin>>n;
T=new Trie(0);
T->tata=T;
for(i=1;i<=n;i++)
{
fin>>cuv[i];
Insert(T,cuv[i],0);
}
fin.close();
}
inline void Construire_Muchii_De_Intoarcere()
{
int i,j;
Trie *nod;
for(i=1;i<=lvlmax;i++)
{
for(j=0;j<nivel[i].size();j++)
{
nod=nivel[i][j]->tata->back;
while(nod)
{
if(nod->fiu[nivel[i][j]->c])
{
nod=nod->fiu[nivel[i][j]->c];
break;
}
nod=nod->back;
}
if(nod)
nivel[i][j]->back=nod;
else
nivel[i][j]->back=T;
}
}
}
inline void Search(Trie *nod,char *c)
{
if(*c==0)
return;
if(nod==NULL)
{
Search(T,c+1);
return;
}
if(nod->fiu[ch])
{
nod->fiu[ch]->nr++;
Search(nod->fiu[ch],c+1);
}
else
Search(nod->back,c);
}
inline void Propaga()
{
int i,j;
for(i=lvlmax;i>0;i--)
for(j=0;j<nivel[i].size();j++)
nivel[i][j]->back->nr+=nivel[i][j]->nr;
}
inline int Query(Trie *nod,char *c)
{
if(*c==0)
return nod->nr;
return Query(nod->fiu[ch],c+1);
}
inline void Afisare()
{
int i;
ofstream fout("ahocorasick.out");
for(i=1;i<=n;i++)
fout<<Query(T,cuv[i])<<"\n";
fout.close();
}
int main()
{
Citire();
Construire_Muchii_De_Intoarcere();
Search(T,A);
Propaga();
Afisare();
return 0;
}