#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 26
#define GETCODE(a) (a - 'a')
typedef struct Node {
char *flag;
struct Node *next[MAX_N], *tail;
} Node;
typedef struct Queue {
Node **d;
int head, file;
} Queue;
int size_cnt;
Queue *initQueue(int x) {
Queue *p = (Queue *)malloc(sizeof(Queue));
p->d = (Node **)malloc(sizeof(Node *) * x);
p->head = p->file = 0;
return p;
}
int empty(Queue *q) {
return q->file ^ q->head;
}
Node* font(Queue *q) {
if (empty(q)) return q->d[q->head];
return 0;
}
void push(Queue *q, Node *root) {
if (!q) return ;
q->d[q->file++] = root;
return ;
}
void initBudeTail(Node *root, Queue *q) {
for (int i = 0; i < MAX_N; i++) root->next[i] && root->next[i] != root && (root->next[i]->tail = root, push(q, root->next[i]), 1) || (root->next[i] = root);
return ;
}
void pop(Queue *q) {
q->head++;
return ;
}
void clearQueue(Queue *q) {
free(q->d);
free(q);
return ;
}
Node *getNewNode() {
++size_cnt;
Node *p = (Node *)malloc(sizeof(Node));
p->tail = 0;
p->flag = NULL;
memset(p->next, 0, sizeof(Node *) * MAX_N);
return p;
}
void __clear(Queue *t) {
Node *p;
while (empty(t)) {
p = font(t);
p->flag && (free(p->flag), 0);
free(p), pop(t);
}
return ;
}
void clear_node(Queue *q) {
if (!empty(q)) return ;
Node *p;
Queue *t = initQueue(size_cnt);
while (empty(q)) {
p = font(q);
for (int i = 0; i < MAX_N; i++) p->next[i] != p->tail->next[i] && (push(q, p->next[i]), 0);
pop(q), push(t, p);
}
__clear(t);
clearQueue(t);
return ;
}
void clear(Node *root) {
if (!root) return ;
Queue *q = initQueue(size_cnt);
initBudeTail(root, q);
clear_node(q);
clearQueue(q);
free(root);
return ;
}
void insert(Node *root, const char *s) {
if (!root) return ;
for (int i = 0; s[i]; i++) {
root->next[GETCODE(s[i])] || (root->next[GETCODE(s[i])] = getNewNode());
root = root->next[GETCODE(s[i])];
}
root->flag = strdup(s);
return ;
}
void buildTail(Node *root) {
Queue *q = initQueue(size_cnt);
initBudeTail(root, q);
while (empty(q)) {
Node *p = font(q), *t;
for (int i = 0; i < MAX_N; i++) {
if (!p->next[i]) {
p->next[i] = p->tail->next[i];
continue;
}
p->next[i]->tail = p->tail->next[i];
push(q, p->next[i]);
}
pop(q);
}
clearQueue(q);
return ;
}
int match_ac(Node *root, const char *s) {
int len = 0;
Node * p = root, *q;
for (int i = 0; s[i]; i++) {
p = p->next[GETCODE(s[i])];
q = p;
while (q != root) {
q->flag && printf("OK: %s
", q->flag) && ++len;
q = q->tail;
}
}
return len;
}
int main() {
int m, n;
scanf("%d", &m);
char s[100] = {0};
Node *root = getNewNode();
for (int i = 0; i < m; i++) {
scanf("%s", s);
insert(root, s);
}
buildTail(root);
scanf("%s", s);
printf("find %s == %d
", s, match_ac(root, s));
clear(root);
return 0;
}