Cod sursa(job #2313226)

Utilizator cezar.plescaCezar Plesca cezar.plesca Data 6 ianuarie 2019 13:41:07
Problema Aho-Corasick Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.14 kb
#include<cstring>
#include<iostream>
#include<malloc.h>
#include<queue>
#include<vector>
#include<list>
#include<algorithm>

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> words;

int* C; // counting frequencies
int* P; // position in words

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.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<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_test17.in","r",stdin);
	freopen("ahocorasick.out","w",stdout);

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

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

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

	vector<string>::iterator vit;
	for(int i=0;i<N;i++){
		scanf("%s",cuv);
		string S(cuv);
	
		vector<string>::iterator vit;
		bool found=false;
		for(vit=words.begin();vit!=words.end();vit++){
			if(S.compare(*vit)==0){
				found=true;
				break;
			}
		}
		if(!found){
			addToTree(words.size());
			P[i]=words.size();
			words.push_back(S);
		}
		else{
			P[i]=vit-words.begin();
		}
	}

	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[P[i]]);
	}

	return 0;
}