Pagini recente » Clasament preoni11 | Clasament test12 | Clasament testconc | Cod sursa (job #1005794) | Cod sursa (job #1086716)
#include<fstream>
#include<cstring>
#define maxn 110
#define maxsir 1000100
#define maxcuv 10010
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
int i,n,ch,p,u,len;
char A[maxsir],s[maxcuv];
struct T{
int nr;
T *next;
T *fiu[27];
T(){
nr=0;
next=NULL;
memset(fiu,NULL,sizeof(fiu));
}
};
T *R=new T;
T *loc[maxn],*C[maxn*maxcuv];
/* bagam in trie toate cuvintele si retinem
pentru fiecare cuvant unde se termina */
void insert(T *nod,char *p,int ind)
{
int ch=(*p)-'a'+1;
if(ch<1||ch>26)
{
loc[ind]=nod;
return;
}
if(nod->fiu[ch]==NULL)
nod->fiu[ch]=new T;
insert(nod->fiu[ch],p+1,ind);
}
int main ()
{
f>>(A+1);
len=strlen(A+1);
f>>n;
for(i=1;i<=n;++i)
{
f>>(s);
insert(R,s,i);
}
p=1; u=0;
C[++u]=R;
R->next=R;
/* facem muchiile de intoarcere (KMP pe trie) */
while(p<=u)
{
T *nod=C[p];
for(ch=1;ch<=26;++ch)
{
if(nod->fiu[ch]==NULL) continue;
T *suf=nod->next;
while(suf->fiu[ch]==NULL&&suf!=R)
suf=suf->next;
if(suf->fiu[ch]!=NULL&&suf->fiu[ch]!=nod->fiu[ch])
nod->fiu[ch]->next = suf->fiu[ch];
else
nod->fiu[ch]->next=R;
C[++u]=nod->fiu[ch];
}
++p;
}
T *nod=R;
/* simulam KMP-ul */
for(i=1;i<=len;++i)
{
ch=A[i]-'a'+1;
while(nod!=R&&nod->fiu[ch]==NULL)
nod=nod->next;
if(nod->fiu[ch]!=NULL)
nod=nod->fiu[ch];
++nod->nr;
}
/* daca avem o aparitie pentru un sir atunci
avem o aparitie si pentru un sufix al acestuia*/
for(i=u;i>=1;--i)
C[i]->next->nr+=C[i]->nr;
for(i=1;i<=n;++i)
g<<loc[i]->nr<<"\n";
return 0;
}