Pagini recente » Cod sursa (job #2682) | Cod sursa (job #1293637) | Cod sursa (job #236825) | Cod sursa (job #3265645) | Cod sursa (job #3297967)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
const int ALPHABET_SIZE = 26;
struct Node {
int next[ALPHABET_SIZE]; // next character edges
int fail; // failure link
vector<int> output; // pattern indices ending at this node
Node() {
fill(next, next + ALPHABET_SIZE, -1);
fail = 0;
}
};
class AhoCorasick {
private:
vector<Node> trie;
vector<string> patterns;
public:
AhoCorasick() {
trie.emplace_back(); // root node
}
void addPattern(const string& pattern) {
int node = 0;
for (char ch : pattern) {
int c = ch - 'a';
if (trie[node].next[c] == -1) {
trie[node].next[c] = trie.size();
trie.emplace_back();
}
node = trie[node].next[c];
}
trie[node].output.push_back(patterns.size());
patterns.push_back(pattern);
}
void build() {
queue<int> q;
for (int c = 0; c < ALPHABET_SIZE; ++c) {
int child = trie[0].next[c];
if (child != -1) {
trie[child].fail = 0;
q.push(child);
}
}
while (!q.empty()) {
int current = q.front(); q.pop();
for (int c = 0; c < ALPHABET_SIZE; ++c) {
int child = trie[current].next[c];
if (child == -1) continue;
int f = trie[current].fail;
while (f && trie[f].next[c] == -1)
f = trie[f].fail;
if (trie[f].next[c] != -1)
f = trie[f].next[c];
trie[child].fail = f;
// Merge output
trie[child].output.insert(
trie[child].output.end(),
trie[f].output.begin(),
trie[f].output.end()
);
q.push(child);
}
}
}
vector<pair<int, string>> search(const string& text) {
vector<pair<int, string>> result;
int node = 0;
for (int i = 0; i < text.size(); ++i) {
int c = text[i] - 'a';
while (node && trie[node].next[c] == -1)
node = trie[node].fail;
if (trie[node].next[c] != -1)
node = trie[node].next[c];
for (int index : trie[node].output) {
result.emplace_back(i - patterns[index].size() + 1, patterns[index]);
}
}
return result;
}
};
int main() {
map<string, int> res;
AhoCorasick ac;
string text;
int num;
in >> text;
in >> num;
for(int i = 0; i<num; i++)
{
string patt;
in >> patt;
ac.addPattern(patt);
res[patt] = 0;
}
ac.build();
auto matches = ac.search(text);
for (auto& match : matches) {
// cout << "Found pattern \"" << match.second
// << "\" at index " << match.first << "\n";
res[match.second]++;
}
for(auto it : res)
{
auto [key, value] = it;
out << value << "\n";
}
return 0;
}