HDU 2222 Keywords Search(AC自动机)
来源:互联网 发布:淘宝卖家版怎么登陆 编辑:程序博客网 时间:2024/06/10 09:59
题目链接:hdu2222
参考博客:点击打开链接
题意:
给你多个模板组成的字典和一个文本,问你文本中出现了多少个模板。
分析:
用模板建立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); 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;}
阅读全文
0 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自动机)
- 复合井盖功能越来越多样化
- asp完整显示数据代码
- 使用util命名空间定义集合
- LVS同步连接状态信息(IPVS Connection Synchronization)
- linux应用开发基础(一)GCC编译器、动态库、静态库使用
- HDU 2222 Keywords Search(AC自动机)
- bash: 一键安装Chrome
- hdu 5945 单调队列优化的DP
- DPDK 内存管理(三)(rte_malloc 内存管理)
- Markdown编辑器改变颜色
- margin和padding属性特点
- C#ASP.MVC后台怎么取前台AJAX传到后台的普通数组。
- 51nod1110 距离之和最小 V3
- python 读取文件注意事项