Pagini recente » Cod sursa (job #1626258) | Cod sursa (job #2337851) | Cod sursa (job #2055315) | Cod sursa (job #1460900) | Cod sursa (job #1958489)
#include <fstream>
#include <cstring>
#include <vector>
using namespace std;
ifstream f("ahocorasick.in");
ofstream g("ahocorasick.out");
const int ln = 10005, la = 1000005;
struct trie {
vector<int> care;
int nr;
trie *urm[30], *fail;
trie() {
fail = 0;
nr = 0;
memset(urm, 0, sizeof(urm));
}
};
trie *inc, *coada[ln*ln], *p;
int n, i, j, st, dr, sol[ln], N;
char orig[la], s[ln];
void pune(trie *t, char *s, int ind) {
if (*s < 'a') {
t -> care.push_back(ind);
return;
}
int c = *s - 'a';
if (t -> urm[c] == 0)
t -> urm[c] = new trie;
pune(t -> urm[c], s+1, ind);
}
void bfs(trie *t) {
trie *y, *dolar, *fr;
coada[st=dr=0] = t;
t -> fail = t;
while (st <= dr) {
fr = coada[st++];
for (i = 0; i < 26; i++) {
if (fr -> urm[i] == 0) continue;
y = fr -> urm[i];
dolar = fr -> fail;
while (dolar -> urm[i] == NULL && dolar != t)
dolar = dolar -> fail;
if (dolar -> urm[i] != NULL && (dolar -> urm[i]) != y)
dolar = dolar -> urm[i];
y -> fail = dolar;
coada[++dr] = y;
}
}
t -> fail = NULL;
}
void bfsinvers() {
for (;dr > 0; dr--) {
p = coada[dr];
if (p -> fail != NULL)
p -> fail -> nr += p -> nr;
for (i = 0; i < p -> care.size(); i++)
sol[ p -> care[i] ] = p -> nr;
}
}
int main() {
inc = new trie;
f >> orig >> n;
for (i = 1; i <= n; i++) {
f >> s;
pune(inc, s, i);
}
N = strlen(orig);
bfs(inc);
p = inc;
int c;
for (i = 0; i < N; i++) {
c = orig[i]-'a';
while (p -> urm[c] == NULL && p != inc)
p = p -> fail;
if (p -> urm[c] != NULL)
p = p -> urm[c];
p -> nr++;
}
bfsinvers();
for (i = 1; i <= n; i++)
g << sol[i] << '\n';
}