HDU 2222 Keywords Search(AC自动机)
2017-07-29 16:48
357 查看
题目链接:hdu2222
参考博客:点击打开链接
题意:
给你多个模板组成的字典和一个文本,问你文本中出现了多少个模板。
分析:
用模板建立AC自动机,然后初始化一个bool vis[]数组,用于标记每个模板,然后用文本串匹配AC自动机,每当扫描到一个单词节点就令vis[]=true.最后在在外面扫描一遍vis数组即可.
即一开始队每个模板的最后一个结点的vis设为true,同时对此结点结束的模板数量val加1,最后统计的时候将这个val全部加上,同时这个结点vis设为false,不可以再一次访问,防止重复计算。
注意:经过测试该题有重复的模板,且如果模板已经出现过多次,只算一次.但是重复的模板要作为新模板同样计数.
(即3个模板a a a ,在文本abc中出现的次数为3)
AC代码:
参考博客:点击打开链接
题意:
给你多个模板组成的字典和一个文本,问你文本中出现了多少个模板。
分析:
用模板建立AC自动机,然后初始化一个bool vis[]数组,用于标记每个模板,然后用文本串匹配AC自动机,每当扫描到一个单词节点就令vis[]=true.最后在在外面扫描一遍vis数组即可.
即一开始队每个模板的最后一个结点的vis设为true,同时对此结点结束的模板数量val加1,最后统计的时候将这个val全部加上,同时这个结点vis设为false,不可以再一次访问,防止重复计算。
注意:经过测试该题有重复的模板,且如果模板已经出现过多次,只算一次.但是重复的模板要作为新模板同样计数.
(即3个模板a a a ,在文本abc中出现的次数为3)
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> using namespace std; const int maxnode=500000+100; const int sigma_size=26; int ans; struct AC_Automata { int ch[maxnode][sigma_size]; int val[maxnode];//用于保存当前单词输入了几遍,当用find扫描文本的时候,只要遇到该单词就+val[i]且让vis[i]=false,使得下次遇到该模板不会重复计算 int f[maxnode]; int last[maxnode]; bool vis[maxnode];//非单词节点vis=0,单词节点vis=1.如果用find找到了单词i节点,那么vis=0. int sz; void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); vis[0]=false; last[0]=f[0]=val[0]=0; } void insert(char *s) { int n=strlen(s),u=0; for(int i=0;i<n;i++) { int id=s[i]-'a'; if(ch[u][id]==0) { vis[sz]=false; ch[u][id]=sz; memset(ch[sz],0,sizeof(ch[sz])); val[sz++]=0; } u=ch[u][id]; } vis[u]=true; val[u]++; } void print(int i) { if(val[i]) { if(vis[i]) { ans+=val[i]; vis[i]=false; } print(last[i]); } } void find(char *s) { int n=strlen(s),j=0; for(int i=0;i<n;i++) { int id=s[i]-'a'; while(j && ch[j][id]==0) j=f[j]; j=ch[j][id]; if(val[j]) print(j); else if(last[j]) print(last[j]); } } void getFail() { queue<int> q; f[0]=0; for(int i=0;i<sigma_size;i++) { int u=ch[0][i]; if(u) { last[u]=f[u]=0; q.push(u); } } while(!q.empty()) { int r=q.front();q.pop(); for(int i=0;i<sigma_size;i++) { int u=ch[r][i]; if(!u) continue; q.push(u); int v=f[r]; while(v && ch[v][i]==0) v=f[v]; f[u]=ch[v][i]; last[u] = val[f[u]]?f[u]:last[f[u]]; } } } }; AC_Automata ac; const int MAXN=1000000+100; char text[MAXN],word[100]; int main() { int T; scanf("%d",&T); while(T--) { ans=0; ac.init(); int n; scanf("%d",&n); c2ce for(int i=1;i<=n;i++) { scanf("%s",word); ac.insert(word); } ac.getFail(); scanf("%s",text); ac.find(text); printf("%d\n",ans); } return 0; }
相关文章推荐
- [HDU 2222] Keywords Search (AC自动机)
- hdu 2222 Keywords Search(ac自动机模板题)
- hdu 2222 Keywords Search (AC自动机)
- Hdu 2222 Keywords Search(AC自动机)
- HDU 2222 Keywords Search(AC自动机入门,模板)
- hdu_2222: Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search(AC自动机)
- HDU - 2222 - Keywords Search(AC自动机)
- HDU 2222 Keywords Search(AC自动机)
- HDU 2222 Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search(ac自动机)
- HDU-2222-Keywords Search(AC自动机模板题)
- HDU 2222 Keywords Search【AC 自动机】
- hdu 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机模版题)
- HDU 2222 Keywords Search (AC自动机)
- hdu 2222 Keywords Search(ac自动机水题)
- hdu 2222 Keywords Search(AC自动机)