Cod sursa(job #983473)

Utilizator Cosmin1490Balan Radu Cosmin Cosmin1490 Data 11 august 2013 21:31:53
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.84 kb
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
 
const string file = "ahocorasick";
 
const string infile = file + ".in";
const string outfile = file + ".out";

const int NMAX = 26;


struct TNode
{
	TNode* g[NMAX];
	TNode* f;
	vector<int> out;
	int count;

	TNode()
	{
		count = 0;
		for(int i = 0; i < NMAX; i++)
		{
			g[i] = NULL;
		}
	}
};

string text;
int N;
vector<int> sol;
stack<TNode*> anti;
TNode* Trie = new TNode();

void insert(TNode* root, string& w, int word)
{
	int l = w.length();
	TNode* c = root;
	for(int i = 0; i < l; i++)
	{
		int index = w[i] - 'a';
		if(c->g[index] == NULL)
		{
			TNode* n = new TNode();
			c->g[index] = n;
		}
		c = c->g[index];
	}
	c->out.push_back(word);
}

void bfs(TNode* root)
{
	queue<TNode*> q;
	
	root->f = root;
	for(int i = 0; i < NMAX; i++)
	{
		if(root->g[i] != NULL)
		{
			q.push(root->g[i]);
			anti.push(root->g[i]);
			root->g[i]->f = root;
		}
	}

	while(q.empty() == false)
	{
		TNode* current = q.front();
		q.pop();

		for(int i = 0; i < NMAX; i++)
		{
			TNode* fail = current->f;
			if(current->g[i] != NULL)
			{
				while(fail->g[i] == NULL && fail != root)
				{
					fail = fail->f;
				}

				if(fail->g[i] != NULL)
				{
					current->g[i]->f = fail->g[i];
				}
				else
				{
					current->g[i]->f = root;
				}

				q.push(current->g[i]);
				anti.push(current->g[i]);
			}
		}
	}


}

void antibfs()
{
	while(anti.empty() == false)
	{
		TNode* current = anti.top();
		anti.pop();

		current->f->count += current->count;
		for(unsigned i = 0; i < current->out.size(); i++)
		{
			sol[current->out[i]] += current->count;
		}
	}
}

int main()
{

	fstream fin(infile.c_str(), ios::in);

	fin >> text;
	fin >> N;
	sol.resize(N);
	for(int i = 0; i < N; i++)
	{
		string w;
		fin >> w;
		insert(Trie, w,i);
	}


	fin.close();

	bfs(Trie);

	int l = text.length();
	TNode* current = Trie;
	for(int i = 0; i < l; i++)
	{
		char c = text[i];
		while(current->g[c - 'a'] == NULL && current != Trie)
		{
			current = current->f;
		}
		if(current->g[c - 'a'] != NULL)
		{
			current =  current->g[c - 'a'];
			current->count++;
		}
	}

	antibfs();

	fstream fout(outfile.c_str(), ios::out);
	for(vector<int>::iterator itr = sol.begin();
		itr != sol.end();
		itr++)
	{
		fout << *itr << "\n";
	}

	fout.close();
}