HDU2222 AC自動機入門

題意: 給出一些關鍵詞,求在下面的字符串中出現的有多少個

分析:AC自動機模板題

注意:1.關鍵詞可能在字符串中出現多次,只算一次

    2.關鍵詞可能相同,都要算

    3.用數組寫會卡內存,開250000差不多能卡過



#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
char str[1000005];
struct Tire{
    Tire *child[26];
    Tire *fail;
    int cnt;
    Tire(){
        cnt=0;
        fail=0;
        memset(child,0,sizeof(child));
    }
};
int idx(char c){
    return c-'a';
}
void insert(char *s,Tire *root){
    Tire *p=root;
    int n=strlen(s);
    for(int i=0;i<n;i++){
        int v=idx(s[i]);
        if(p->child[v]==0){
            p->child[v]=new Tire;
        }
        p=p->child[v];
    }
    p->cnt++;
}
void getFail(Tire *root){
    Tire *front;
    queue<Tire *> q;
    q.push(root);
    while(!q.empty()){
        front=q.front();
        q.pop();
        for(int i=0;i<26;i++){
            if(front->child[i]!=NULL){
                if(front==root)
                front->child[i]->fail=root;
                else {
                    Tire *tmp=front;
                    while(tmp->fail!=NULL){
                        if(tmp->fail->child[i]!=NULL){
                            front->child[i]->fail=tmp->fail->child[i];
                            break;
                        }
                        tmp=tmp->fail;
                    }
                    if(tmp->fail==NULL)
                    front->child[i]->fail=root;
                }
                q.push(front->child[i]);
            }
        }
    }
}
int find(char *T,Tire *root){
    int n=strlen(T);
    Tire *p=root;
    Tire *tmp=NULL;
    int k,ans=0;
    for(int i=0;i<n;i++){
        k=idx(T[i]);
        while(p!=root&&p->child[k]==NULL){
            p=p->fail;
        }
        if(p->child[k]!=NULL){
            p=p->child[k];
            tmp=p;
            while(tmp!=root){
                ans+=tmp->cnt;
                tmp->cnt=0;
                tmp=tmp->fail;
            }
        }
    }
    return ans;
}
int main()
{
     int t,n;
    scanf("%d",&t);
    while(t--){
        Tire *root=new Tire;
        scanf("%d",&n);
        while(n--){
            scanf("%s",str);
            insert(str,root);
        }
        scanf("%s",str);
        getFail(root);
        printf("%d\n",find(str,root));

    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章