Pagini recente » Cod sursa (job #798664) | Autentificare | Cod sursa (job #2103774) | Cod sursa (job #714294) | Cod sursa (job #1761629)
#include <fstream>
#include <string>
#include <vector>
#include <queue>
#define l(x) (x - 'a')
using namespace std;
typedef class Nod * arbore;
class Nod
{
public:
char val;
arbore tata;
arbore fail;
vector <int> cuvant; // 0 daca nu e cuvant
arbore fii[30];
Nod()
{
for (int i = 0; i < 30; i++)
fii[i] = 0;
}
};
Nod E;
void adauga(string s, int cuvant);
void creeare_fail(arbore k);
void baga_cuvant(arbore k);
int frc[110];
int main()
{
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
string a, c;
in >> a;
int n;
in >> n;
for (int i = 1; i <= n; i++) {
in >> c;
adauga(c, i);
}
E.fail = &E;
E.val = '$';
for (int i = 0; i < 30; i++)
if (E.fii[i] != 0)
creeare_fail(E.fii[i]);
baga_cuvant(&E);
arbore k = &E;
for (auto i : a) {
bool modif = 1;
while (k != &E && k->val != i && k->fii[l(i)] == 0)
k = k->fail, modif = 0;
if ((k->val != i || modif) && k->fii[l(i)] != 0)
k = k->fii[l(i)];
if (k->val == i) {
for (auto j : k->cuvant)
frc[j]++;
}
}
for (int i = 1; i <= n; i++)
out << frc[i] << '\n';
return 0;
}
void adauga(string s, int cuvant)
{
arbore k = &E, l;
for (auto i : s) {
if (k->fii[l(i)] != 0)
k = k->fii[l(i)];
else {
l = k;
k->fii[l(i)] = new Nod;
k = k->fii[l(i)];
k->val = i;
k->tata = l;
}
}
k->cuvant.push_back(cuvant);
}
void creeare_fail(arbore k)
{
k->fail = k->tata->fail;
while (k->fail->val != '$' && k->fail->fii[l(k->val)] == 0 && k->fail->val != k->val)
k->fail = k->fail->fail;
if (k->fail->val != k->val && k->fail->fii[l(k->val)] != 0 && k->tata->val != '$')
k->fail = k->fail->fii[l(k->val)];
for (int i = 0; i < 30; i++)
if (k->fii[i] != 0)
creeare_fail(k->fii[i]);
}
void baga_cuvant(arbore k)
{
queue <arbore> q;
q.push(k);
while (!q.empty()) {
k = q.front();
q.pop();
for (auto i : k->fail->cuvant)
k->cuvant.push_back(i);
for (int i = 0; i < 30; i++)
if (k->fii[i] != 0)
q.push(k->fii[i]);
}
}