Pagini recente » Cod sursa (job #274550) | Cod sursa (job #1685296) | Cod sursa (job #1618787) | Cod sursa (job #7329) | Cod sursa (job #3250405)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
#include <cstring>
using namespace std;
const int MAXC = 26;
ifstream in ("ahocorasick.in");
ofstream out ("ahocorasick.out");
struct TrieNode {
unordered_map<char, TrieNode*> children;
TrieNode* fail;
vector<int> output;
TrieNode() : fail(nullptr) {}
};
struct AhoCorasick {
TrieNode* root;
vector<int> keywordCount;
AhoCorasick() {
root = new TrieNode();
}
void insert(const string &word, int index) {
TrieNode* current = root;
for (char ch : word) {
if (current->children.find(ch) == current->children.end()) {
current->children[ch] = new TrieNode();
}
current = current->children[ch];
}
current->output.push_back(index);
}
void buildFailureLinks() {
queue<TrieNode*> q;
root->fail = root;
for (auto &child : root->children) {
child.second->fail = root;
q.push(child.second);
}
while (!q.empty()) {
TrieNode* current = q.front();
q.pop();
for (auto &child : current->children) {
char ch = child.first;
TrieNode* nextNode = child.second;
TrieNode* failState = current->fail;
while (failState != root && failState->children.find(ch) == failState->children.end()) {
failState = failState->fail;
}
if (failState->children.find(ch) != failState->children.end()) {
nextNode->fail = failState->children[ch];
} else {
nextNode->fail = root;
}
nextNode->output.insert(nextNode->output.end(), nextNode->fail->output.begin(), nextNode->fail->output.end());
q.push(nextNode);
}
}
}
void search(const string &text) {
TrieNode* current = root;
for (int i = 0; i < text.size(); ++i) {
char ch = text[i];
while (current != root && current->children.find(ch) == current->children.end()) {
current = current->fail;
}
if (current->children.find(ch) != current->children.end()) {
current = current->children[ch];
}
for (int wordIndex : current->output) {
keywordCount[wordIndex]++;
}
}
}
void processText(const string &text, const vector<string> &keywords) {
keywordCount.assign(keywords.size(), 0);
for (int i = 0; i < keywords.size(); ++i) {
insert(keywords[i], i);
}
buildFailureLinks();
search(text);
for (int i = 0; i < keywords.size(); ++i) {
out << keywordCount[i] << endl;
}
}
};
int main() {
string A;
int n;
in >> A >> n;
vector<string> words(n);
for (int i = 0; i < n; ++i) {
in >> words[i];
}
AhoCorasick automaton;
automaton.processText(A, words);
return 0;
}