Pagini recente » Cod sursa (job #198760) | Cod sursa (job #2438618) | Cod sursa (job #1079034) | Cod sursa (job #2969842) | Cod sursa (job #3250406)
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <fstream>
using namespace std;
struct TrieNode {
vector<int> output;
TrieNode *children[26];
TrieNode *failure;
TrieNode() {
memset(children, 0, sizeof(children));
failure = nullptr;
}
};
class AhoCorasick {
private:
TrieNode *root;
vector<string> words;
public:
AhoCorasick() {
root = new TrieNode();
}
void insert(const string &word, int index) {
TrieNode *current = root;
for (char c : word) {
int idx = c - 'a';
if (!current->children[idx]) {
current->children[idx] = new TrieNode();
}
current = current->children[idx];
}
current->output.push_back(index);
}
void build() {
queue<TrieNode*> q;
root->failure = root;
for (int i = 0; i < 26; i++) {
if (root->children[i]) {
root->children[i]->failure = root;
q.push(root->children[i]);
} else {
root->children[i] = root;
}
}
while (!q.empty()) {
TrieNode *current = q.front();
q.pop();
for (int i = 0; i < 26; i++) {
if (current->children[i]) {
TrieNode *failureNode = current->failure;
while (failureNode->children[i] == nullptr) {
failureNode = failureNode->failure;
}
current->children[i]->failure = failureNode->children[i];
current->children[i]->output.insert(current->children[i]->output.end(),
failureNode->children[i]->output.begin(),
failureNode->children[i]->output.end());
q.push(current->children[i]);
}
}
}
}
vector<int> search(const string &text) {
vector<int> occurrences(words.size(), 0);
TrieNode *current = root;
for (char c : text) {
int idx = c - 'a';
while (current->children[idx] == nullptr) {
current = current->failure;
}
current = current->children[idx];
for (int index : current->output) {
occurrences[index]++;
}
}
return occurrences;
}
void addWord(const string &word) {
words.push_back(word);
insert(word, words.size() - 1);
}
};
int main() {
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string A;
fin >> A;
int n;
fin >> n;
AhoCorasick ac;
for (int i = 0; i < n; i++) {
string word;
fin>>word;
ac.addWord(word);
}
ac.build();
vector<int> occurrences = ac.search(A);
for (int count : occurrences) {
fout << count << endl;
}
return 0;
}