1. 程式人生 > >[hdu1277]全文檢索(AC自動機)

[hdu1277]全文檢索(AC自動機)

數組 size using blog ans emp print 檢索 sca

解題關鍵: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("\n"); 92 } 93 else printf("No key can be found !\n"); 94 } 95 return 0; 96 }

[hdu1277]全文檢索(AC自動機)