Cod sursa(job #782575)

Utilizator darrenRares Buhai darren Data 28 august 2012 12:41:52
Problema Aho-Corasick Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <cstring>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <queue>

using namespace std;

struct trie
{
	int val;
	trie* son[26];
	trie* next;
	
	trie()
	{
		memset(son, 0, sizeof(son));
		val = 0;
		next = 0;
	}
};

trie* T = new trie;

trie* add(trie* now, char* chn)
{
	if (*chn == 0) return now;
	if (now->son[*chn - 'a'] == 0)
	{
		trie* aux = new trie;
		now->son[*chn - 'a'] = aux;
	}
	
	now = now->son[*chn - 'a'];
	++chn;
	return add(now, chn);
}

int N;
char A[1000002], B[102][10002];
queue<trie*> Q;
trie* where[102];

void Dfs(trie* now)
{
	for (int i = 0; i < 26; ++i)
		if (now->son[i])
			Dfs(now->son[i]);
	if (now->next)
		now->next->val += now->val;
}

int main()
{
	ifstream fin("ahocorasick.in");
	ofstream fout("ahocorasick.out");
	
	fin >> A >> N;
	
	for (int i = 1; i <= N; ++i)
	{
		fin >> B[i];
		where[i] = add(T, B[i]);
	}
	
	Q.push(T);
	while (!Q.empty())
	{
		trie* now = Q.front();
		Q.pop();
		
		for (int i = 0; i < 26; ++i)
			if (now->son[i] != 0)
			{
				trie* aux = now->next;
				while (aux && aux->son[i] == 0)
					aux = aux->next;
				
				if (aux)
					now->son[i]->next = aux->son[i];
				else
					now->son[i]->next = T;
				
				Q.push(now->son[i]);
			}
	}
	
	trie* now = T;
	for (int i = 0; A[i] != 0; ++i)
	{
		while (now && now->son[A[i] - 'a'] == 0)
			now = now->next;
		if (!now)
			now = T;
		else
		{
			now = now->son[A[i] - 'a'];
			++now->val;
		}
	}
	
	Dfs(T);
	
	for (int i = 1; i <= N; ++i)
		fout << where[i]->val << '\n';
	
	fin.close();
	fout.close();
}