Cod sursa(job #2313190)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 6 ianuarie 2019 12:18:11
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include<string>
#include<iostream>
#include<malloc.h>
#include<queue>
#include<set>
#include<list>

using namespace std;

#define SIZEALFABET 26

typedef struct Nod{
	int fii[SIZEALFABET];	
	list<int> output;
	list<pair<int,int>> links;
	Nod() {
        memset(fii,0,sizeof(fii));
    }
}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

vector<string> P;

void addToTree(int indexCuv){
	int l=strlen(cuv);
	int nod=1;
	int index;
	for(int i=0;i<l;i++){
		index=cuv[i]-'a';
		if(tree[nod].fii[index]==0){
			// creare nod nou
			nbNod++;
			tree[nod].fii[index]=nbNod;
			tree[nod].links.push_back(make_pair(index,nbNod));
			Nod newnod;
			tree.push_back(newnod);
			nod=nbNod;
		}
		else{
			// legatura existenta
			nod=tree[nod].fii[index];
		}
	}
	tree[nod].output.push_back(indexCuv);
}

int** g;
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());
			}
		}
	}
}

int* C;

void searchText(){
	int q = 1; // initial state (root)
	int m=strlen(T);
	list<int>::iterator it;
	
	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++){
				C[*it]++;
			}
		}
	}
}

int main() {

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

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

	C=(int*)calloc(N,sizeof(int));

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

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

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

	for(int i='a';i<='z'; i++){
		g[1][i-'a']=1;
	}
	list<pair<int,int>>::iterator it;
	for(it=tree[1].links.begin(); it!=tree[1].links.end(); it++){
		g[1][it->first]=it->second;
	}
	
	for(int i=2;i<=nbNod;i++){
		for(it=tree[i].links.begin(); it!=tree[i].links.end(); it++){
			g[i][it->first]=it->second;
		}
	}
	
	f=(int*)calloc(nbNod+1,sizeof(int));

	secondPhase();

	searchText();
	
	for(int i=0; i<N; i++){
		printf("%d\n",C[i]);
	}

	return 0;
}