Template of ACoCorasickAutomata

LA 4670
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
struct Node
{
    struct Node *fail;
    struct Node *next[26];
    int tot;
    int id;
    Node()
    {
        fail = NULL;
        memset(next, NULL, sizeof(next));
        tot = 0;
        id = -1;
    }
}*que[5000000];
int ans[200];
char keyword[155][75], T[1000005];
int head, tail;
void build_tree(char *str, int idx, Node *root)
{
    struct Node *p = root;
    int i = 0, index;
    while (str[i])
    {
        index = str[i] - 'a';
        if (p->next[index] == NULL)
        {
            p->next[index] = new Node();
        }
        p = p->next[index];
        i++;
    }
    p->tot++;
    p->id = idx;
}
void build_ac_automation(Node *root)
{
    root->fail = NULL;
    que[head++] = root;
    while (head != tail)
    {
        struct Node *temp = que[tail++];
        struct Node *p = NULL;
        for (int i = 0; i < 26; i++)
        {
            if (temp->next[i] != NULL)
            {
                if (temp == root)
                {
                    temp->next[i]->fail = root;
                }
                else /// temp != root
                {
                    p = temp->fail;
                    while (p != NULL)
                    {
                        if (p->next[i] != NULL)
                        {
                            temp->next[i]->fail = p->next[i];
                            break;
                        }
                        p = p->fail;
                    }
                    if (p == NULL)
                    {
                        temp->next[i]->fail = root;
                    }
                }
                que[head++] = temp->next[i];
            }
        }
    }
}
void query(Node *root)
{
    int i = 0, index;
    Node *p = root;
    while (T[i])
    {
        index = T[i] - 'a';
        while (p->next[index] == NULL && p != root)
        {
            p = p->fail;
        }
        p = p->next[index];
        p = (p == NULL) ? root : p; ///????
        Node *temp = p;
        while (temp != root && temp->tot != -1)
        {
            ans[temp->id]++;
            temp = temp->fail;
        }
        i++;
    }
}

int main()
{
    int n;
    while (scanf("%d%*c", &n), n)
    {
        struct Node *root = new Node();
        head = tail = 0;
        memset(ans, 0, sizeof(ans));
        for (int i = 0; i < n; i++)
        {
            gets(keyword[i]);
            build_tree(keyword[i], i + 1, root);
        }
        build_ac_automation(root);
        gets(T);
        query(root);
        int maxn = -1;
        for (int i = 1; i <= n; i++)
        {
            if(ans[i] > maxn)
                maxn = ans[i];
        }
        printf("%d\n", maxn);
        for (int i = 1; i <= n; i++)
        {
            if (ans[i] == maxn)
            {
                printf("%s\n", keyword[i - 1]);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(数据结构,template,AC自动机)