Cod sursa(job #2312727)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 5 ianuarie 2019 14:02:15
Problema Aho-Corasick Scor 0
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.85 kb
#include<hash_map>
#include<string>
#include<iostream>
#include<malloc.h>
#include<queue>

using namespace std;
using namespace stdext;

typedef struct Nod{
	hash_map <char,int> fii;	
	list<string> output;
}Nod;

vector<Nod> tree;

int nbNod=1;

#define MAXTEXT 1000000
char T[MAXTEXT+1];

#define MAXCUV 10000
char cuv[MAXCUV+1];

int N; // numarul de cuvinte
hash_map<string,int> C;
vector<string> P;

void addToTree(){
	int l=strlen(cuv);
	int nod=1;
	
	hash_map<char,int>::iterator it;
	for(int i=0;i<l;i++){
		it = tree[nod].fii.find(cuv[i]);
		if(it==tree[nod].fii.end()){
			// creare nod nou
			nbNod++;
			tree[nod].fii[cuv[i]]=nbNod;
			Nod newnod;
			tree.push_back(newnod);
			nod=nbNod;
		}
		else{
			// legatura existenta
			nod=tree[nod].fii[cuv[i]];
		}
	}
	string S(cuv);
	tree[nod].output.push_back(S);
}

int** g;
int sizeAlhabet='z'-'a'+1;
int *f;

void secondPhase(){
	queue<int> Q;
	int q;
	for(int i='a';i<='z';i++){
		q=g[1][i-'a'];
		if(q!=1){
			f[q]=1;
			Q.push(q);
		}
	}
	int r,u,v;
	while(!Q.empty()){
		r=Q.front(); Q.pop();
		for(int i='a';i<='z';i++){
			u=g[r][i-'a'];
			if(u!=0){
				Q.push(u);
				v=f[r];
				while(g[v][i-'a']==0)
					v=f[v];
				f[u]=g[v][i-'a'];
				//tree[u].output.splice(tree[u].output.end(),tree[f[u]].output);
				tree[u].output.insert(tree[u].output.end(), tree[f[u]].output.begin(), tree[f[u]].output.end());
			}
		}
	}
}

void searchText(){
	int q = 1; // initial state (root)
	int m=strlen(T);
	list<string>::iterator it;
	hash_map<string,int>::iterator hit;
	for(int i=0; i< m; i++){
		while(g[q][T[i]-'a']==0)
			q=f[q];
		q=g[q][T[i]-'a']; // follow a goto
		if(!tree[q].output.empty()){
			for(it=tree[q].output.begin(); it!=tree[q].output.end(); it++){
				hit=C.find(*it);
				hit->second++;
			}
		}
	}
}

int main() {

	freopen("ahocorasick.in","r",stdin);
	//freopen("aho_test19.in","r",stdin);
	freopen("ahocorasick.out","w",stdout);

	scanf("%s",T);
	scanf("%d",&N);

	Nod root;
	tree.push_back(root);
	tree.push_back(root);

	for(int i=0;i<N;i++){
		scanf("%s",cuv);
		addToTree();
		string S(cuv);
		C.insert(make_pair(S,0));
		P.push_back(S);
	}

	g=(int**)calloc(nbNod+1,sizeof(int*));
	for(int i=0;i<=nbNod; i++){
		g[i]=(int*)calloc(sizeAlhabet,sizeof(int));
	}

	hash_map<char,int>::iterator it;	
	for(int i='a';i<='z'; i++){
		g[1][i-'a']=1;
	}
	for(it=tree[1].fii.begin(); it!=tree[1].fii.end(); it++){
		g[1][it->first-'a']=it->second;
	}
	
	for(int i=2;i<=nbNod;i++){
		for(it=tree[i].fii.begin(); it!=tree[i].fii.end(); it++){
			g[i][it->first-'a']=it->second;
		}
	}

	f=(int*)calloc(nbNod+1,sizeof(int));

	secondPhase();

	searchText();
	
	hash_map<string,int>::iterator hit;
	for(int i=0; i<N; i++){
		hit=C.find(P[i]);
		printf("%d\n",hit->second);
	}

	return 0;
}