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