Cod sursa(job #931686)

Utilizator raulstoinStoin Raul raulstoin Data 28 martie 2013 13:52:42
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.63 kb
#include<fstream>
#include<vector>
#include<cstring>
#define Z s[i]-'a'
#define NMAX 10005
#define NOD Q[i-1]
using namespace std;
struct TRIE
{
	int nr;
	TRIE *fii[26],*fail;
	vector<short> nod;
	TRIE()
	{
		memset(fii,0,sizeof fii);
		nr=0;
		fail=0;
	}
}*G;
vector<TRIE*> Q;
char s[NMAX*100],cuv[NMAX];
int n,sol[NMAX];
inline void add(char s[],short ind)
{
	TRIE *t=G;
	short i;
	for(i=0;s[i] && t->fii[Z];t=t->fii[Z],i++);
	if(!s[i])
	{
		t->nod.push_back(ind);
		return;
	}
	for(;s[i];t=t->fii[Z],i++)
		t->fii[Z]=new TRIE;
	t->nod.push_back(ind);
}
void read()
{
	ifstream fin("ahocorasick.in");
	fin>>s;
	fin>>n;
	G=new TRIE;
	for(short i=0;i<n;i++)
	{
		fin>>cuv;
		add(cuv,i);
	}
	fin.close();
}
inline void BFS()
{
	TRIE *p;
	G->fail=G;
	Q.push_back(G);
	for(size_t i=1;i<=Q.size();i++)
		for(int j=0;j<26;j++)
			if(NOD->fii[j])
			{
				for(p=NOD->fail;p!=G && !(p->fii[j]);p=p->fail);
				
				if(p->fii[j] && p->fii[j]!=NOD->fii[j])
					p=p->fii[j];
				NOD->fii[j]->fail=p;
				Q.push_back(NOD->fii[j]);
			}
	G->fail=0;
}
inline void BFS_back()
{
	for(size_t i=Q.size();i;i--)
	{
		if(NOD->fail)
			NOD->fail->nr+=NOD->nr;
		for(size_t j=0;j<NOD->nod.size();j++)
			sol[NOD->nod[j]]=NOD->nr;
	}
}
inline void down()
{
	TRIE *p=G;
	int l=strlen(s);
	for(int i=0;i<l;i++)
	{
		for(;!p->fii[Z] && p!=G;p=p->fail);
		if(p->fii[Z])
			p=p->fii[Z];
		p->nr++;
	}
}
void print()
{
	ofstream fout("ahocorasick.out");
	for(int i=0;i<n;i++)
		fout<<sol[i]<<'\n';
	fout.close();
}
int main()
{
	read();
	BFS();
	down();
	BFS_back();
	print();
	return 0;
}