Pagini recente » Cod sursa (job #2785310) | Cod sursa (job #585991) | Cod sursa (job #621293) | Cod sursa (job #2594233) | Cod sursa (job #3232836)
#include <fstream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
struct TrieNode {
unordered_map<char, TrieNode*> children;
TrieNode* fail;
vector<int> output;
};
class AhoCorasick {
public:
AhoCorasick(const vector<string>& patterns) {
root = new TrieNode();
buildTrie(patterns);
buildFailureLinks();
}
vector<int> search(const string& text) {
vector<int> result(patterns.size(), 0);
TrieNode* current = root;
for (char c : text) {
while (current != root && current->children.find(c) == current->children.end()) {
current = current->fail;
}
if (current->children.find(c) != current->children.end()) {
current = current->children[c];
}
for (int patternIndex : current->output) {
result[patternIndex]++;
}
}
return result;
}
private:
TrieNode* root;
vector<string> patterns;
void buildTrie(const vector<string>& patterns) {
this->patterns = patterns;
for (int i = 0; i < patterns.size(); i++) {
const string& pattern = patterns[i];
TrieNode* current = root;
for (char c : pattern) {
if (current->children.find(c) == current->children.end()) {
current->children[c] = new TrieNode();
}
current = current->children[c];
}
current->output.push_back(i);
}
}
void buildFailureLinks() {
queue<TrieNode*> q;
for (auto& [c, child] : root->children) {
child->fail = root;
q.push(child);
}
while (!q.empty()) {
TrieNode* current = q.front();
q.pop();
for (auto& [c, child] : current->children) {
TrieNode* fail = current->fail;
while (fail != root && fail->children.find(c) == fail->children.end()) {
fail = fail->fail;
}
if (fail->children.find(c) != fail->children.end()) {
child->fail = fail->children[c];
} else {
child->fail = root;
}
child->output.insert(child->output.end(), child->fail->output.begin(), child->fail->output.end());
q.push(child);
}
}
}
};
int main() {
ifstream cin("ahocorasick.in");
ofstream cout("ahocorasick.out");
// Read input
string A;
cin >> A;
int n;
cin >> n;
vector<string> patterns(n);
for (int i = 0; i < n; ++i) {
cin >> patterns[i];
}
// Initialize Aho-Corasick
AhoCorasick ac(patterns);
// Search patterns in text A
vector<int> result = ac.search(A);
// Output results
for (int count : result) {
cout << count << endl;
}
return 0;
}