Pagini recente » Cod sursa (job #780177) | Cod sursa (job #290338) | Cod sursa (job #2041896) | Cod sursa (job #1456611) | Cod sursa (job #2322478)
#include <vector>
#include <algorithm>
#include <queue>
#include <fstream>
constexpr int nChars = 26;
struct Node {
Node() : children(nChars, NULL)
{
failNode = NULL;
};
std::vector<Node*> children;
std::vector<int> words;
Node* failNode;
};
void addWordToTree(Node* currentNode, char word[], unsigned int index)
{
int ch;
unsigned int i = 0;
while (word[i] != 0)
{
ch = word[i] - 'a';
if (currentNode->children[ch] == NULL)
{
currentNode->children[ch] = new Node;
}
currentNode = currentNode->children[ch];
++i;
}
currentNode->words.push_back(index);
}
void assignFailNode(Node* root, Node* node, unsigned int ch)
{
Node* currentNode = node;
while (root != currentNode)
{
currentNode = currentNode->failNode;
if (NULL != currentNode->children[ch])
{
node->children[ch]->failNode = currentNode->children[ch];
currentNode = root;
}
}
if (NULL == node->children[ch]->failNode)
{
node->children[ch]->failNode = root;
}
Node* child = node->children[ch];
child->words.insert(child->words.end(),
child->failNode->words.begin(),
child->failNode->words.end());
}
void linkFailNodes(Node* root)
{
root->failNode = root;
std::queue<Node*> q;
for (unsigned int i = 0; i < nChars; ++i)
{
if (root->children[i] != NULL)
{
root->children[i]->failNode = root;
q.push(root->children[i]);
}
}
Node* currentNode = NULL;
while (!q.empty())
{
currentNode = q.front();
q.pop();
for (unsigned int i = 0; i < nChars; ++i)
{
if (NULL != currentNode->children[i])
{
assignFailNode(root, currentNode, i);
q.push(currentNode->children[i]);
}
}
}
}
void processText(Node *root, char text[], unsigned int frequence[])
{
Node* currentNode = root;
int ch;
unsigned int i = 0;
while (text[i] != 0)
{
ch = text[i] - 'a';
while (currentNode->children[ch] == NULL && currentNode != root)
{
currentNode = currentNode->failNode;
}
if (currentNode->children[ch] != NULL)
{
currentNode = currentNode->children[ch];
for (const auto& word : currentNode->words)
{
++frequence[word];
}
}
++i;
}
}
char text[1000001];
char word[10001];
unsigned int frequence[101];
unsigned int n;
int main()
{
Node* root = new Node;
std::ifstream fin("ahocorasick.in");
std::ofstream fout("ahocorasick.out");
fin >> text;
fin >> n;
unsigned int index = 0;
while (!fin.eof())
{
fin >> word;
addWordToTree(root, word, index);
++index;
}
linkFailNodes(root);
processText(root, text, frequence);
for (unsigned int i = 0; i < n; ++i)
{
fout << frequence[i] << '\n';
}
return 0;
}