Cod sursa(job #1359705)

Utilizator SebiSebiPirtoaca George Sebastian SebiSebi Data 25 februarie 2015 01:14:47
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<vector>
#include<string.h>
using namespace std;

#define NMAX 1000002
#define LMAX 10002
#define CMAX 101
#define ALPHA 26

struct Trie {
	Trie *fail,*urm[ALPHA];
	int nr;
	vector <int> poz;
	Trie() {
		fail=NULL;
		memset(urm,0,sizeof(urm));
		nr=0;
	}
};

char sir[NMAX],cuv[LMAX];
Trie *c[LMAX*LMAX];
int sol[CMAX];

inline void adauga(Trie *p, char *s, int poz)
{
	if(*s=='\0') {
		p->poz.push_back(poz);
		return ;
	}
	if(p->urm[*s-'a']==NULL) 
		p->urm[*s-'a']=(Trie*)calloc(1,sizeof(Trie));
	adauga(p->urm[*s-'a'],s+1,poz);
}

int bfs(Trie *p)
{
	int st,dr,i;
	Trie *nod,*aux;
	st=1;
	dr=1;
	c[st]=p;
	while(st<=dr) {
		nod=c[st];
		st++;
		for(i=0;i<=ALPHA-1;i++) {
			if(nod->urm[i]==NULL)
				continue;
			aux=nod->fail;
			if(aux) {
				while(aux->urm[i]==NULL) {
					aux=aux->fail;
					if(aux==NULL)
						break;
				}
			}
			if(nod!=p && aux==NULL) {
				if(p->urm[i]!=NULL)
					aux=p;
			}
			if(aux)
				aux=aux->urm[i];
			nod->urm[i]->fail=aux;
			c[++dr]=nod->urm[i];
		}
	}
	return dr;
}

void rbfs(int i)
{
	for( ;i>=1;i--) {
		if(c[i]->fail!=NULL)
			c[i]->fail->nr=c[i]->fail->nr+c[i]->nr;
		for(vector <int> :: iterator it=(c[i]->poz).begin();it!=(c[i]->poz).end();it++)
			sol[*it]=c[i]->nr;
	}
}

int main()
{
	int n,m,i,l;
	Trie *p,*aux;
	ifstream f("ahocorasick.in");
	ofstream g("ahocorasick.out");
	f>>(sir+1);
	f>>n;
	p=(Trie*)calloc(1,sizeof(Trie));
	for(i=1;i<=n;i++) {
		f>>(cuv+1);
		adauga(p,cuv+1,i);
	}
	f.close();
	m=bfs(p);
	aux=p;
	l=strlen(sir+1);
	for(i=1;i<=l;i++) {
		while(aux->urm[sir[i]-'a']==NULL) {
			aux=aux->fail;
			if(aux==NULL)
				break;
		}
		if(aux==NULL && p->urm[sir[i]-'a']!=NULL)
			aux=p;
		if(aux) {
			aux=aux->urm[sir[i]-'a'];
			aux->nr++;
		}
		if(aux==NULL)
			aux=p;
	}
	rbfs(m);
	for(i=1;i<=n;i++) 
		g<<sol[i]<<'\n';
	g.close();
	return 0;
}