Pagini recente » Cod sursa (job #539863) | Cod sursa (job #2068432) | Cod sursa (job #1039828) | Cod sursa (job #3033569) | Cod sursa (job #1922591)
#include <stdio.h>
#include <stdlib.h>
int chval(char c) {
return c - 'a';
}
char ch(int i) {
return (char)(i + 'a');
}
typedef struct Trie {
struct Trie *parent;
struct Trie *child[26];
struct Trie *suffix;
struct Trie *sufend;
char end;
int id;
} Trie;
Trie root;
void put(char *str, int id) {
Trie *trie = &root;
int i;
for (i = 0; str[i]; ++i) {
int v = chval(str[i]);
if (!trie->child[v]) {
trie->child[v] = calloc(1, sizeof(Trie));
trie->child[v]->parent = trie;
trie->child[v]->id = id;
}
trie = trie->child[v];
}
trie->end = 1;
}
void calcsuf(Trie *trie, char c) {
if (!trie) return;
trie->suffix = 0;
if (c) {
trie->suffix = &root;
int val = chval(c);
Trie *parent = trie->parent;
while (parent) {
if (parent->child[val]) {
Trie *child = parent->child[val];
if (child != trie) {
trie->suffix = child;
break;
}
}
parent = parent->suffix;
}
}
int i;
for (i = 0; i < 26; ++i) {
if (trie->child[i]) calcsuf(trie->child[i], ch(i));
}
}
void calcsufend(Trie *trie) {
if (!trie) return;
Trie *suffix = trie->suffix;
while (suffix) {
if (suffix->end) break;
suffix = suffix->suffix;
}
trie->sufend = suffix;
int i;
for (i = 0; i < 26; ++i) {
if (trie->child[i]) calcsufend(trie->child[i]);
}
}
int C[100];
void countall(Trie *trie) {
if (trie->end) C[trie->id]++;
Trie *sufend = trie->sufend;
while (sufend) {
C[sufend->id]++;
sufend = sufend->sufend;
}
}
Trie *go(Trie *state, char c) {
int v = chval(c);
if (state->child[v]) return state->child[v];
Trie *suffix = state->suffix;
while (suffix) {
if (suffix->child[v]) return suffix->child[v];
suffix = suffix->suffix;
}
return &root;
}
char A[1000001];
char B[10001];
int main() {
freopen("ahocorasick.in", "r", stdin);
freopen("ahocorasick.out", "w", stdout);
scanf("%s", A);
int i, n;
scanf("%i", &n);
for (i = 0; i < n; ++i) {
scanf("%s", B);
put(B, i);
}
calcsuf(&root, 0);
calcsufend(&root);
Trie *state = &root;
for (i = 0; A[i]; ++i) {
state = go(state, A[i]);
countall(state);
}
for (i = 0; i < n; ++i) printf("%i\n", C[i]);
return 0;
}