Cod sursa(job #1086716)

Utilizator Kira96Denis Mita Kira96 Data 18 ianuarie 2014 14:39:10
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#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;
}