Pagini recente » Cod sursa (job #2985084) | Cod sursa (job #2065307) | Cod sursa (job #1663453) | Cod sursa (job #1478031) | Cod sursa (job #971630)
Cod sursa(job #971630)
#include <fstream>
#include <string>
const int ALPHABET_SIZE('z' - 'a' + 1);
const int MAX_SIZE(1000001);
const int MAX_N(101);
struct Trie
{
int occ = 0;
struct Trie *node [ALPHABET_SIZE] = {nullptr};
struct Trie *fail = nullptr;
} *Automaton;
inline void Initialise (struct Trie *&node)
{
node = new struct Trie;
}
inline void Insert (struct Trie *&node, std::string &word)
{
if (!node)
Initialise(node);
struct Trie *iterator(node);
for (int index(0) ; index < word.size() ; ++index)
{
if (!iterator->node[word[index] - 'a'])
Initialise(iterator->node[word[index] - 'a']);
iterator = iterator->node[word[index] - 'a'];
}
}
inline int Query (std::string word)
{
struct Trie *iterator(Automaton);
for (int i(0) ; i < word.size() ; ++i)
iterator = iterator->node[word[i] - 'a'];
return iterator->occ;
}
int n;
std::string Strings [MAX_N];
std::string s;
int Matches [MAX_N];
struct Trie *Queue [MAX_SIZE];
struct Trie **Push(Queue + 1), **Pop(Queue);
inline void Read (void)
{
std::ifstream input("ahocorasick.in");
input >> s;
input >> n;
for (int index(0) ; index < n ; ++index)
input >> Strings[index];
input.close();
}
inline void Print (void)
{
std::ofstream output("ahocorasick.out");
for (int index(0) ; index < n ; ++index)
output << Query(Strings[index]) << '\n';
output.close();
}
inline void Build (void)
{
for (int index(0) ; index < n ; ++index)
Insert(Automaton,Strings[index]);
}
inline void BreadthFirstSearch (void)
{
Automaton->fail = Automaton;
Queue[0] = Automaton;
struct Trie *node, *fail;
int i;
while (Pop != Push)
{
node = *Pop;
++Pop;
for (i = 0 ; i < ALPHABET_SIZE ; ++i)
if (node->node[i])
{
for (fail = node->fail ; fail != Automaton && !fail->node[i] ; fail = fail->fail)
/* do nothing */;
if (fail != node)
fail = fail->node[i];
if (!fail)
fail = Automaton;
node->node[i]->fail = fail;
*Push = node->node[i];
++Push;
}
}
}
inline void AhoCorasick (void)
{
struct Trie *iterator(Automaton);
for (int index(0) ; index < s.size() ; ++index)
{
while (!iterator->node[s[index] - 'a'] && iterator != Automaton)
iterator = iterator->fail;
if (iterator->node[s[index] - 'a'])
iterator = iterator->node[s[index] - 'a'];
++iterator->occ;
}
}
inline void ReverseBreadthFirstSearch (void)
{
--Pop;
struct Trie *iterator;
while (Pop >= Queue)
{
iterator = *Pop;
iterator->fail->occ += iterator->occ;
--Pop;
}
}
int main (void)
{
Read();
Build();
BreadthFirstSearch();
AhoCorasick();
ReverseBreadthFirstSearch();
Print();
return 0;
}