Cod sursa(job #664065)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 19 ianuarie 2012 16:01:45
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include<fstream>
#include<vector>
#define NMAX 1000100
#define NMAx 10010
#define CH(x) x-'a'
using namespace std;
char s[NMAX],a[NMAx];
int n,nrc,v[NMAx];
vector <int> sol[NMAx];

struct Trie{int inf;
			Trie *fiu[26],*fail;
			Trie() {
				inf=0;
				fail=0;
				for(int i=0;i<26;i++)
					fiu[i]=0;
				}
			};
Trie *T=new Trie;
Trie *deque[NMAX];

void paint(int k) {
	int i;
	for(i=0;i<sol[k].size();i++)
		v[sol[k][i]]++;
}
void solve() {
	int i;
	Trie *nod=T;
	for(i=0;s[i];i++) {
		while(!nod->fiu[CH(s[i])]&&nod!=T)
			nod=nod->fail;
		if(nod->fiu[CH(s[i])])
			nod=nod->fiu[CH(s[i])];
		if(nod->inf)
			paint(nod->inf);
		}
}
void fail() {
	int i,j,nr=0;
	Trie *nod,*p;
	for(i=0;i<26;i++)
		if(T->fiu[i]) {
			T->fiu[i]->fail=T;
			deque[nr++]=T->fiu[i];
			}
	for(i=0;i<nr;i++) {
		nod=deque[i];
		for(j=0;j<26;j++) {
			p=nod;
			if(nod->fiu[j]) {
				while(p!=T) {
					if(p->fail->fiu[j]) {
						nod->fiu[j]->fail=p->fail->fiu[j];
						break;
						}
					else
						p=p->fail;
					}
				p=nod->fiu[j];
				if(p->fail==0)
					p->fail=T;
				deque[nr++]=p;
				if(p->fail->inf) {
					if(!p->inf) {
						p->inf=++nrc;
						sol[nrc].insert(sol[nrc].end(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
						}
					else
						sol[p->inf].insert(sol[p->inf].begin(),sol[p->fail->inf].begin(),sol[p->fail->inf].end());
					}
				}
			}
		}
}
void citire() {
	int i,j;
	Trie *nod;
	ifstream in("ahocorasick.in");
	in.getline(s,NMAX-2);
	in>>n;
	in.getline(a,2);
	for(i=0;i<n;i++) {
		in.getline(a,NMAx);
		nod=T;
		for(j=0;a[j];j++) {
			if(nod->fiu[CH(a[j])]==0)
				nod->fiu[CH(a[j])]=new Trie;
			nod=nod->fiu[CH(a[j])];
			}
		++nrc;
		if(nod->inf==0) {
			nod->inf=nrc;
			sol[nrc].push_back(nrc);
			}
		else
			sol[nod->inf].push_back(nrc);
		}
	in.close();
}
void afis() {
	int i;
	ofstream out("ahocorasick.out");
	for(i=1;i<=n;i++)
		out<<v[i]<<'\n';
	out.close();
}
int main() {
	citire();
	fail();
	solve();
	afis();
	return 0;
}