AC自动机, 多模匹配, 字符串匹配

#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\n", 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\n", s, match_ac(root, s));
        clear(root);
        return 0;
}
posted @ 2021-10-23 10:39  代码附体  阅读(119)  评论(0编辑  收藏  举报