hdu2896(查找文本串中的模式串)&&3065
题:http://acm.hdu.edu.cn/showproblem.php?pid=2896
分析:ac自动机模板
注意细节,1、128个ascii码都要;
2、只要关键码含有只输出一个编号就行
#include<iostream> #include<queue> #include<algorithm> #include<cstring> #include<string> using namespace std; typedef long long ll; #define pb push_back const int M=501*201; const int N=505; int vis[N]; int n; struct ac{ int tot,root; int trie[M][130],end[M],fail[M]; int newnode(){ for(int i=0;i<130;i++){ trie[tot][i]=-1; } end[tot]=0; tot++; return tot-1; } void init(){ tot=0; root=newnode(); } void insert(char *buf,int id){ int now=root,len=strlen(buf); for(int i=0;i<len;i++){ if(trie[now][buf[i]]==-1) trie[now][buf[i]]=newnode(); now=trie[now][buf[i]]; } end[now]=id; } void getfail(){ queue<int>que; while(!que.empty()) que.pop(); fail[root]=root; for(int i=0;i<130;i++) if(trie[root][i]==-1) trie[root][i]=0; else{ fail[trie[root][i]]=root; que.push(trie[root][i]); } while(!que.empty()){ int now=que.front(); que.pop(); for(int i=0;i<130;i++){ if(trie[now][i]!=-1){ fail[trie[now][i]]=trie[fail[now]][i]; que.push(trie[now][i]); } else trie[now][i]=trie[fail[now]][i]; } } } int query(char *buf){ int len=strlen(buf); int ans=0; int now=root; for(int i=0;i<len;i++){ now=trie[now][buf[i]]; int tmp=now; while(tmp!=root){ if(end[tmp]!=0){ vis[end[tmp]]=1; ans++; } tmp=fail[tmp]; } } return ans; } }AC; char s1[10004],s[202]; int main(){ while(~scanf("%d",&n)){ AC.init(); int ans=0; for(int i=1;i<=n;i++){ scanf("%s",s); AC.insert(s,i); } AC.getfail(); int m; scanf("%d",&m); for(int i=1;i<=m;i++){ memset(vis,0,sizeof(vis)); scanf("%s",s1); if(AC.query(s1)>=1){ printf("web %d:",i); for(int j=1;j<=n;j++) if(vis[j]) printf(" %d",j); printf("\n"); ans++; } } printf("total: %d\n",ans); } return 0; }
题:http://acm.hdu.edu.cn/showproblem.php?pid=3065
分析:只要将上题的vis改为技术数组即可
#include<iostream> #include<queue> #include<algorithm> #include<cstring> #include<string> using namespace std; typedef long long ll; #define pb push_back const int M=51*1001; const int N=1001; char s[N][55],s1[2000002]; int n; struct ac{ int tot,root; int trie[M][130],end[M],fail[M],vis[M]; int newnode(){ for(int i=0;i<130;i++){ trie[tot][i]=-1; } end[tot++]=0; return tot-1; } void init(){ tot=0; root=newnode(); } void insert(char *buf,int id){ int len=strlen(buf); int now=root; for(int i=0;i<len;i++){ if(trie[now][buf[i]]==-1) trie[now][buf[i]]=newnode(); now=trie[now][buf[i]]; } end[now]=id; } void getfail(){ queue<int>que; while(!que.empty()){ que.pop(); } fail[root]=root; for(int i=0;i<130;i++){ if(trie[root][i]==-1) trie[root][i]=root; else{ fail[trie[root][i]]=root; que.push(trie[root][i]); } } while(!que.empty()){ int now=que.front(); que.pop(); for(int i=0;i<130;i++){ if(trie[now][i]!=-1){ fail[trie[now][i]]=trie[fail[now]][i]; que.push(trie[now][i]); } else trie[now][i]=trie[fail[now]][i]; } } } void query(char *buf){ memset(vis,0,sizeof(vis)); int len=strlen(buf); int now=root; for(int i=0;i<len;i++){ now=trie[now][buf[i]]; int tmp=now; while(tmp!=root){ if(end[tmp]!=0) vis[end[tmp]]++; tmp=fail[tmp]; } } for(int i=1;i<=n;i++) if(vis[i]>0) printf("%s: %d\n",s[i],vis[i]); } }AC; int main(){ while(scanf("%d",&n)==1){ AC.init(); for(int i=1;i<=n;i++){ scanf("%s",s[i]); AC.insert(s[i],i); } AC.getfail(); scanf("%s",s1); AC.query(s1); } return 0; }