Pagini recente » Cod sursa (job #1367307) | Cod sursa (job #2265654) | Cod sursa (job #2773765) | Cod sursa (job #3001564) | Cod sursa (job #3231153)
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#include <unordered_map>
using namespace std;
struct Nod {
unordered_map<char, Nod*> copii;
Nod* fail = nullptr;
vector<int> terminari;
};
class AhoCorasick {
public:
AhoCorasick(const vector<string>& cuvinte) {
radacina = new Nod();
for (int i = 0; i < cuvinte.size(); ++i)
adaugaCuvant(cuvinte[i], i);
construiesteFail();
}
void cauta(const string& text, vector<int>& rezultate) {
Nod* nodCurent = radacina;
for (int i = 0; i < text.size(); ++i) {
while (nodCurent not_eq radacina and nodCurent->copii.find(text[i]) == nodCurent->copii.end())
nodCurent = nodCurent->fail;
if (nodCurent->copii.find(text[i]) not_eq nodCurent->copii.end())
nodCurent = nodCurent->copii[text[i]];
else
nodCurent = radacina;
for (int id : nodCurent->terminari)
rezultate[id]++;
}
}
private:
Nod* radacina;
void adaugaCuvant(const string& cuvant, int id) {
Nod* nodCurent = radacina;
for (char c : cuvant) {
if (nodCurent->copii.find(c) == nodCurent->copii.end())
nodCurent->copii[c] = new Nod();
nodCurent = nodCurent->copii[c];
}
nodCurent->terminari.push_back(id);
}
void construiesteFail() {
queue<Nod*> q;
for (auto& pereche : radacina->copii) {
pereche.second->fail = radacina;
q.push(pereche.second);
}
while (not q.empty()) {
Nod* nodCurent = q.front();
q.pop();
for (auto& pereche : nodCurent->copii) {
char c = pereche.first;
Nod* copil = pereche.second;
Nod* fail = nodCurent->fail;
while (fail not_eq radacina and fail->copii.find(c) == fail->copii.end())
fail = fail->fail;
if (fail->copii.find(c) not_eq fail->copii.end())
copil->fail = fail->copii[c];
else
copil->fail = radacina;
copil->terminari.insert(copil->terminari.end(), copil->fail->terminari.begin(), copil->fail->terminari.end());
q.push(copil);
}
}
}
};
int main() {
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");
string A;
int n;
fin >> A >> n;
vector<string> cuvinte(n);
for (int i = 0; i < n; ++i)
fin >> cuvinte[i];
AhoCorasick ac(cuvinte);
vector<int> rezultate(n, 0);
ac.cauta(A, rezultate);
for (int i = 0; i < n; ++i)
fout << rezultate[i] << '\n';
return 0;
}