[hdu1277]全文检索(AC自动机)

解题关键:AC自动机模板题,注意字符匹配时若无法匹配,直接用%s即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=12;
 5 const int MAXN=600010;
 6 int num,ans[10020],nn;
 7 bool vis[600010];
 8 bool flag=false;
 9 struct Trie{//数组形式 
10     int Next[MAXN][N],Fail[MAXN],End[MAXN],root,tot;//大小为所以匹配字符串的总和 
11     int newnode(){//结构体内部用 
12         for(int i=0;i<N;i++) Next[tot][i]=-1;
13         End[tot++]=0;
14         return tot-1;
15     }
16     void init(){
17         tot=0;
18         root=newnode();
19     }
20     void insert(char buf[],int x){
21         int len=strlen(buf);
22         int now=root;//now是temp指针 
23         for(int i=0;i<len;i++){
24             int k=buf[i]-'0';
25             if(Next[now][k]==-1)  Next[now][k]=newnode();//next数组代表的是下一个字符索引 
26             now=Next[now][k];
27         }
28         End[now]=x;//end数组是当前字符串的个数.字典中可能有相同的单词,若只算一次,改为1. 
29     }
30     void build(){//构造fail指针,后缀是某些前缀 
31         queue<int>que;
32         Fail[root]=root;
33         for(int i=0;i<N;i++){ 
34             if(Next[root][i]==-1) Next[root][i]=root;
35             else{
36                 Fail[Next[root][i]]=root;
37                 que.push(Next[root][i]);
38             }
39         } 
40         while(!que.empty()){//bfs,会将所有的匹配子串都遍历到 
41             int now=que.front();
42             que.pop();
43             for(int i=0;i<N;i++){
44                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
45                 else{
46                     Fail[Next[now][i]]=Next[Fail[now]][i];//fail指向最长的 
47                     que.push(Next[now][i]);
48                 }
49             }
50         }
51     }
52     void query(char buf[]){
53         int len=strlen(buf),now=root;
54         for(int i=0;i<len;i++){
55             now=Next[now][buf[i]-'0'];
56             int temp=now;
57             while(temp!=root){
58                 if(End[temp]&&!vis[temp]) ans[nn++]=End[temp],vis[temp]=true,flag=true;
59                 temp=Fail[temp];
60             }
61         }
62     }
63 };
64 
65 Trie ac;
66 char buf[60004],buf2[60004],tmp[6002];
67 int n,m;
68 int main(){
69     while(scanf("%d%d",&m,&n)!=EOF){
70         memset(ans,0,sizeof ans);
71         memset(vis,0,sizeof vis);
72         nn=0;
73         ac.init();
74         int t=0;
75         flag=false;
76         for(int i=1;i<=m;i++){
77             scanf("%s",tmp);
78             strcat(buf,tmp);
79         }
80            for(int i=1;i<=n;i++){
81                scanf("%*s %*s %d] %s",&num,buf2);
82                ac.insert(buf2,num);
83         }
84            ac.build();//不要忘记build 
85         ac.query(buf);
86         if(flag){
87             printf("Found key:");
88             for(int i=0;i<nn;i++){
89                 printf(" [Key No. %d]",ans[i]);
90             }
91             printf("
");
92         }
93         else printf("No key can be found !
");
94     }
95     return 0;
96 } 
原文地址:https://www.cnblogs.com/elpsycongroo/p/7507964.html