Cod sursa(job #1397555)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 23 martie 2015 16:45:12
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.76 kb
#include <fstream>
#include <vector>
#include <string>
#include <cctype>

const unsigned DICT_SIZE='z'-'a'+1;

std::vector<unsigned> nrmatch;

class Node{
 public:
	static unsigned NRTOT;

	Node *ch[DICT_SIZE];
	Node *fail;
	std::vector<unsigned> isendof;
	unsigned nrm;

	Node(){
		fail=0;
		nrm=0;
		for(unsigned i=0;i<DICT_SIZE;++i) ch[i]=0;
		++NRTOT;
	}
};
unsigned Node::NRTOT=0;


void trie_insert(Node *t, const char *s, const unsigned ind){
	if(!std::isalpha(*s)){
		t->isendof.push_back(ind);
	}
	else{
		unsigned next= (*s)-'a';
		if(t->ch[next]==0) t->ch[next]=new Node;
		trie_insert(t->ch[next], s+1, ind);
	}
}

std::vector<Node *> q; unsigned si,ei;

void bfs(Node *t){
	q.resize(Node::NRTOT);
	q[0]=t;
	si=0; ei=0;
	t->fail=t;

	while(si<=ei){
		Node *curr = q[si++];

		for(unsigned i=0;i<DICT_SIZE;++i)
			if(curr->ch[i]!=0){
				q[++ei]=curr->ch[i];

				Node *cf=curr->fail;
				while(cf!=t&&cf->ch[i]==0) cf=cf->fail;

				if(cf->ch[i]!=0&&cf->ch[i]!=curr->ch[i]) curr->ch[i]->fail=cf->ch[i];
				else curr->ch[i]->fail=t;
			}
	}
	t->fail=0;
}

void reversebfs(){
	for(int i=ei;i>=0;--i){
		Node *curr=q[i];
		if(curr->fail!=0) curr->fail->nrm += curr->nrm;
		for(unsigned j=0;j<curr->isendof.size();++j) nrmatch[curr->isendof[j]]+=curr->nrm;
	}
}


int main(){
	std::ifstream fin("ahocorasick.in");
	std::ofstream fout("ahocorasick.out");

	std::string text;
	fin>>text;

	unsigned n; fin>>n;
	nrmatch.resize(n,0);

	Node *t=new Node;

	for(unsigned i=0;i<n;++i){
		std::string s;
		fin>>s;
		trie_insert(t, s.c_str(), i);
	}

	bfs(t);

	Node *c=t;
	for(unsigned i=0;i<text.size();++i){
		unsigned next=text[i]-'a';
		while(c!=t&&c->ch[next]==0) c=c->fail;
		if(c->ch[next]!=0) c=c->ch[next];
		++c->nrm;
	}

	reversebfs();
	for(unsigned i=0;i<n;++i) fout<<nrmatch[i]<<'\n';
}