hdu2222 ac自動機裸題

前幾天講了ac自動機,今天才a了第一道模板題.(o(╯□╰)o),我還是太弱了(畢竟蒟蒻).
問題難度很小,我註釋的很詳細了,應該能懂吧

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int t,tou,tail,n;
char s[55],s1[100005]; 
struct node{
    node *fail;
    node *net[26];
    int ci;
    node()
    {
        fail=NULL;
        ci=0;
        for (int i=0;i<26;i++)
        {
            net[i]=NULL;
        }
    }
}*q[500005];
node *root; 
void trie_build(char *s) //建立Trie  
{  
    int temp, len;  
    node *p = root;  
    len = strlen(s);  
    for(int i = 0; i < len; ++i)  
    {  
        temp = s[i] - 'a';  
        if(p->net[temp] == NULL)  
            p->net[temp] = new node();  
        p = p->net[temp];  
    }  
    p->ci++;  
}  
void ac_build()
{
    q[tail++]=root;//初始化 
    while(tou!=tail)
    {
        node *p=q[tou++];
        node *temp=NULL;//pop()
        for(int i = 0; i < 26; ++i)  
        {  
            if(p->net[i] != NULL)  
            {  
                if(p == root) //第一個元素fail必指向根  
                    p->net[i]->fail = root;  
                else  
                {  
                    temp = p->fail; //失敗指針  
                    while(temp != NULL) //匹配爲空 or 找到匹配
                    {  
                        if(temp->net[i] != NULL)  
                        {  
                            p->net[i]->fail = temp->net[i];  
                            break;  
                        }  
                        temp = temp->fail;  
                    }  
                    if(temp == NULL) //爲空則從頭匹配  
                        p->net[i]->fail = root;  
                }  
                q[tail++] = p->net[i]; //入隊  
            }  
        }  
    }  
}  
int query()
{
    node *p=root;
    int len=strlen(s1);
    int ans=0;
    for(int i=0;i<len;i++)
    {
        int temp=s1[i]-'a';
        while (p->net[temp]==NULL&&p!=root)//跳轉到fail指針 
        {
            p=p->fail;
        }
        p=p->net[temp];
        if (p==NULL) p=root; 
        node *w=p;
        while (w!=root&&w->ci!=-1)
        {
            ans+=w->ci;
            w->ci=-1;
            w=w->fail; 
        } 
    } 
    return ans; 
} 
void readdata()
{

    int t, num;  
    scanf("%d", &t);  
    while(t--)  
    {  
        tou= tail = 0;  
        root = new node();  
        scanf("%d", &num);  
        getchar();  
        for(int i = 0; i < num; ++i)  
        {  
            gets(s);  
            trie_build(s);  
        }  
        ac_build();  
        scanf("%s", s1);  
        printf("%d\n", query());  
    } 
}
int main()
{
    readdata();
}
發佈了25 篇原創文章 · 獲贊 2 · 訪問量 6721
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章