当前位置:编程学习 > C/C++ >>

hdu 2896 AC自动机模版题

题意:输出出现模式串的id,还是用end记录id就可以了。
本题有个关键点:“以上字符串中字符都是ASCII码可见字符(不包括回车)。”  -----也就说AC自动机的Trie树需要128个单词分支。
 
 
#include <cstdio>  
#include <cstring>  
#include <queue>  
  
using namespace std;  
  
const int maxw = 210 *500 + 10;  
const int sigma_size = 128;  
const int maxl = 10000 + 10;  
  
struct Trie{  
    int next[maxw][sigma_size],fail[maxw],end[maxw];  
    int root,L;  
    int newnode(){  
        for(int i=0;i<sigma_size;i++)  
            next[L][i]=-1;  
        end[L++]=-1;  
        return L-1;  
    }  
    void init(){  
        L=0;  
        root=newnode();  
    }  
    void insert(const char *s,int id){  
        int now=root,len=strlen(s);  
        for(int i=0;i<len;i++){  
            if(next[now][s[i]]==-1)  
                next[now][s[i]]=newnode();  
            now=next[now][s[i]];  
        }  
        end[now]=id;  
    }  
    void build(){  
        queue<int>Q;  
        fail[root]=root;  
        for(int i=0;i<sigma_size;i++)  
            if(next[root][i]==-1)  
                next[root][i]=root;  
            else{  
                fail[next[root][i]]=root;  
                Q.push(next[root][i]);  
            }  
        while(!Q.empty()){  
            int now=Q.front();  
            Q.pop();  
            for(int i=0;i<sigma_size;i++)  
                if(next[now][i]==-1)  
                    next[now][i]=next[fail[now]][i];  
                else{  
                    fail[next[now][i]]=next[fail[now]][i];  
                    Q.push(next[now][i]);  
                }  
        }  
    }  
    bool used[500 + 10];  
    bool query(const char *buf,int n,int id){  
        int now=root,len=strlen(buf);  
        memset(used,false,sizeof(used));  
        bool flag =false;  
        for(int i=0;i<len;i++){  
            now=next[now][buf[i]];  
            int tmp=now;  
            while(tmp!=root){  
                if(end[tmp]!=-1){  
                    used[end[tmp]]=true;  
                    flag=true;  
                }  
            tmp=fail[tmp];  
            }  
        }  
        if(!flag) return false;  
        printf("web %d:",id);  
        for(int i=1;i<=n;i++)  
            if(used[i])    printf(" %d",i);  
        printf("\n");  
        return true;  
    }  
};  
  
char buf[maxl];  
Trie ac;  
  
int main()  
{  
    int n,m;  
    while(~scanf("%d",&n)){  
        ac.init();  
        for(int i=1;i<=n;i++){  
            scanf("%s",buf);  
            ac.insert(buf,i);  
        }  
        ac.build();  
        int ans=0;  
        scanf("%d",&m);  
        for(int i=1;i<=m;i++){  
            scanf("%s",buf);  
            if(ac.query(buf,n,i))  ans++;  
        }  
        printf("total: %d\n",ans);  
    }  
    return 0;  
}  

 

 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,