Pagini recente » Cod sursa (job #2133678) | Cod sursa (job #323884) | Borderou de evaluare (job #1355087) | Cod sursa (job #1203127) | Cod sursa (job #2341972)
#include <fstream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
struct TrieNode
{
TrieNode* sons[26] = {};
TrieNode *suffix = nullptr;
vector<int> indexes;
int count = 0;
};
void Insert(TrieNode *root, int index, char const *str)
{
while (*str) {
if (!root->sons[*str - 'a']) {
root->sons[*str - 'a'] = new TrieNode;
}
root = root->sons[*str - 'a'];
str += 1;
}
root->indexes.push_back(index);
}
TrieNode* FindSuffixNode(TrieNode *father, char ch)
{
if (!father->suffix) {
return father;
}
auto other = father->suffix;
while (other->suffix && !other->sons[ch - 'a']) {
other = other->suffix;
}
if (other->sons[ch - 'a']) {
other = other->sons[ch - 'a'];
}
return other;
}
vector<TrieNode*> MakeAutomaton(TrieNode *root)
{
vector<TrieNode*> order;
order.push_back(root);
size_t index = 0;
while (index < order.size()) {
auto node = order[index++];
for (auto ch = 'a'; ch <= 'z'; ch += 1) {
if (!node->sons[ch - 'a']) {
continue;
}
auto son = node->sons[ch - 'a'];
son->suffix = FindSuffixNode(node, ch);
order.push_back(son);
}
}
return order;
}
void ExtractCount(const vector<TrieNode*> &order, vector<int> &count)
{
for (int i = order.size() - 1; i >= 0; i -= 1) {
auto node = order[i];
for (size_t j = 0; j < node->indexes.size(); j += 1) {
count[node->indexes[j]] = node->count;
}
if (node->suffix) {
node->suffix->count += node->count;
}
}
}
vector<int> CountAppearances(int words,
const vector<TrieNode*> &order,
char const *text)
{
auto *node = order[0];
while (*text) {
while (!node->sons[*text - 'a'] && node->suffix) {
node = node->suffix;
}
if (node->sons[*text - 'a']) {
node = node->sons[*text - 'a'];
}
node->count += 1;
text += 1;
}
vector<int> count(words, 0);
ExtractCount(order, count);
return count;
}
int main()
{
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string text;
getline(fin, text);
int words;
fin >> words;
fin.get();
TrieNode *trie = new TrieNode;
for (auto i = 0; i < words; i += 1) {
string word;
getline(fin, word);
Insert(trie, i, word.c_str());
}
auto order = MakeAutomaton(trie);
auto res = CountAppearances(words, order, text.c_str());
for (auto i = 0; i < words; i += 1) {
fout << res[i] << "\n";
}
return 0;
}