Pagini recente » Cod sursa (job #1630859) | Clasament preoni6c | Cod sursa (job #2225116) | Cod sursa (job #495249) | Cod sursa (job #1980802)
#include <cstdio>
#include <ctype.h>
const int MAX_S1 = 100000;
const int SIGMA = 26;
const int MAX_SIR = 100;
const int MAX_S2 = 10000;
char sir1[MAX_S1];
char query[MAX_SIR][MAX_S2+1];
char nextch(FILE *fin) {
char ch = fgetc(fin);
while(ch == ' ')
ch = fgetc(fin);
return ch;
}
struct Aho {
int fr;
char papach;
Aho* fiu[SIGMA];
Aho *fail, *papa;
Aho() {
for(int i = 0; i < SIGMA; ++i)
fiu[i] = NULL;
fail = papa = NULL;
fr = 0;
papach = -1;
}
};
Aho *queue[MAX_SIR * (MAX_S2+1)];
int st, dr;
void add(Aho *t, char *x) {
if(*x != '\0') {
char ch = (*x - 'a');
if(t->fiu[ch] == NULL) {
t->fiu[ch] = new Aho();
t->fiu[ch]->papa = t;
t->fiu[ch]->papach = ch;
}
add(t->fiu[ch], x + 1);
}
}
int queryAho(Aho *t, char *x) {
if(*x == '\0')
return t->fr;
else
return queryAho(t->fiu[(*x - 'a')], x + 1);
}
void bfs(Aho *t) {
st = dr = 0;
queue[dr++] = t;
t->fail = t;
while(st < dr) {
Aho *nod = queue[st++];
for(int i = 0; i < SIGMA; ++i)
if(nod->fiu[i] != NULL)
queue[dr++] = nod->fiu[i];
if(nod != t) {
Aho *cursor = nod->papa->fail;
char ch = nod->papach;
while(cursor != t && cursor->fiu[ch] == NULL)
cursor = cursor -> fail;
if(cursor->fiu[ch] == NULL)
nod->fail = t;
else
nod->fail = cursor->fiu[ch];
if(nod->fail == nod)
nod->fail = t;
}
}
}
void antibfs(Aho *x) { //in queue voi avea deja nodurile in ordine
for(int i = dr - 1; i >= 0; --i) {
Aho *nod = queue[i];
nod->fail->fr += nod -> fr;
}
}
int main() {
int n, s1 = 0;
char ch;
Aho *x = new Aho(), *cursor;
FILE *fin = fopen("ahocorasick.in", "r");
ch = nextch(fin);
while(isalpha(ch)) {
sir1[s1++] = ch;
ch = nextch(fin);
}
fscanf(fin, "%d", &n);
ch = nextch(fin);
for(int i = 0; i < n; ++i) {
ch = nextch(fin);
int s = 0;
while(isalpha(ch)) {
query[i][s++] = ch;
ch = nextch(fin);
}
add(x, query[i]);
}
fclose(fin);
bfs(x);
cursor = x;
for(int i = 0; i < s1; ++i) {
ch = sir1[i] - 'a';
while(cursor != x && cursor -> fiu[ch] == NULL)
cursor = cursor -> fail;
if(cursor -> fiu[ch] != NULL) {
cursor = cursor -> fiu[ch];
cursor -> fr++;
}
}
antibfs(x);
FILE *fout = fopen("ahocorasick.out", "w");
for(int i = 0; i < n; ++i)
fprintf(fout, "%d\n", queryAho(x, query[i]));
fclose(fout);
return 0;
}