Pagini recente » Cod sursa (job #2236090) | Cod sursa (job #2981631) | Cod sursa (job #3228900) | Cod sursa (job #580049) | Cod sursa (job #1765949)
#include <fstream>
#include <vector>
#include <string>
#include <queue>
#include <cstring>
#include <cstdlib>
#define f(a) ((a) - 'a')
using namespace std;
typedef struct Aho * Arbore;
const int SIGMA = 27;
struct Aho
{
Arbore fail, fii[SIGMA];
int match;
vector <int> dict;
inline Aho()
{
memset(fii, 0x00, sizeof(fii));
match = 0;
fail = 0;
}
};
void add(string &a, int cuv, Arbore k);
vector <Arbore> make_fail(Arbore k);
void autom(Arbore k, string &a);
vector <int> make_calc(Arbore k, vector <Arbore> &bfs, int s);
int main()
{
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
string a, b;
int n;
Arbore R = new Aho();
in >> a >> n;
for (int i = 0; i < n; i++) {
in >> b;
add(b, i, R);
}
R->fail = R;
vector <Arbore> bfs = make_fail(R);
autom(R, a);
vector <int> rez = make_calc(R, bfs, n);
for (auto i : rez)
out << i << '\n';
return 0;
}
void add(string & a, int cuv, Arbore k)
{
for (const char &c : a) {
if (!k->fii[f(c)])
k->fii[f(c)] = new Aho();
k = k->fii[f(c)];
}
k->dict.push_back(cuv);
}
vector<Arbore> make_fail(Arbore k)
{
Arbore tmp, a;
vector <Arbore> bfs;
queue <Arbore> q;
q.push(k);
bfs.push_back(k);
while (!q.empty()) {
a = q.front();
q.pop();
for (int i = 0; i < SIGMA; i++) {
if (a->fii[i]) {
for (tmp = a->fail; tmp != k && !tmp->fii[i]; tmp = tmp->fail);
if (tmp->fii[i] && tmp != a)
tmp = tmp->fii[i];
a->fii[i]->fail = tmp;
q.push(a->fii[i]);
bfs.push_back(a->fii[i]);
}
}
}
return bfs;
}
void autom(Arbore k, string & a)
{
Arbore act = k;
for (const char &c: a) {
while (act != k && !act->fii[f(c)])
act = act->fail;
if (act->fii[f(c)]) {
act = act->fii[f(c)];
act->match++;
}
}
}
vector<int> make_calc(Arbore k, vector<Arbore>& bfs, int s)
{
vector <int> rez(s, 0);
for (reverse_iterator <vector <Arbore>::iterator> it = bfs.rbegin(); it != bfs.rend(); it++) {
for (int x : (*it)->dict)
rez[x] += (*it)->match;
(*it)->fail->match += (*it)->match;
}
return rez;
}