ac自动机入门模板

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>

using namespace std;

typedef struct Trie_Node
{
    Trie_Node *fail;
    Trie_Node *next[26];
    int cnt;
}Trie;

char p[55];
char s[1000000];

void insert_word(char *key, Trie *root)
{
    Trie *p = root;
    int len = strlen(key);
    for(int i = 0; i < len; i++)
    {
       if(p->next[key[i] - 'a'] == NULL){
        Trie *temp = new Trie;
        for(int j = 0;j < 26; j++)
            temp->next[j] = NULL;
        temp->cnt = 0;
        temp->fail = NULL;
        p->next[key[i] - 'a'] = temp;
       }
    p = p->next[key[i] - 'a'];
    }
    p->cnt++;
}

void get_fail(Trie *root)
{
    root->fail = NULL;
    Trie *p = NULL;
    queue<Trie *>Q;
    Q.push(root);
    while(!Q.empty())
    {
        Trie *temp = Q.front();
        Q.pop();
        for(int i = 0; i < 26; i++)
        {
            if(temp->next[i] != NULL)
            {
                if(temp == root)
                {
                    temp->next[i]->fail = root;
                }
                else
                {
                    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;
                }
                Q.push(temp->next[i]);
            }
        }
    }
}

int query(Trie *root)
{
    int ans = 0;
    int len = strlen(s);
    Trie *p = root;
    for(int i = 0; i < len; i++)
    {
        int index = s[i] - 'a';
        while(p->next[index] == NULL && p != root) p = p->fail;
        p = p->next[index];
        if(p == NULL)
            p = root;
        Trie *temp = p;
        while(temp != root)
        {
            ans += temp->cnt;
            temp->cnt = 0;
            temp = temp->fail;
        }
        //printf("sdasda\n");

    }
    //printf("%d\n", ans);
    return ans;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        Trie *root = new Trie;
        root->cnt = 0;
        root->fail = NULL;
        for(int i = 0; i < 26; i++)
                    root->next[i] = NULL;
        for(int i = 0; i < n; i++)
        {
            scanf("%s", p);
            insert_word(p, root);
        }
        get_fail(root);
        scanf("%s", s);
        //54545printf("sdfadsa\n");
        printf("%d\n", query(root));
    }

}
发布了40 篇原创文章 · 获赞 13 · 访问量 871

猜你喜欢

转载自blog.csdn.net/weixin_43891021/article/details/97623353