Pagini recente » Cod sursa (job #266078) | Cod sursa (job #216997) | Cod sursa (job #215952) | Cod sursa (job #856379) | Cod sursa (job #2322493)
#include <vector>
#include <algorithm>
#include <queue>
#include <cstdio>
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];
int n;
int main()
{
Node* root = new Node;
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
scanf("%s", text);
scanf("%d", &n);
for(int index=0; index < n; ++index)
{
scanf("%s", word);
addWordToTree(root, word, index);
}
linkFailNodes(root);
processText(root, text, frequence);
for(int i=0; i<n; ++i)
{
printf("%d\n", frequence[i]);
}
return 0;
}