HDU-2222 Keywords Search(AC自动机)
2016-07-23 22:48
295 查看
字典树+KMP
AC自动机 最基本的入门题了,就是求目标串中出现了几个模式串。
AC自动机 最基本的入门题了,就是求目标串中出现了几个模式串。
#include<cstdio> #include<algorithm> #include<string.h> #include<queue> using namespace std; const int maxn = 1e6 + 5; struct node{ int nxt[26],ed; void Init(){ for(int i=0;i<26;i++) nxt[i]=-1; ed=0; } }L[maxn]; char st[maxn]; int tot,fail[maxn]; void add(){ int len=strlen(st),tmp,now=0; for(int i=0;i<len;i++){ tmp=st[i]-'a'; if(L[now].nxt[tmp]==-1){ L[++tot].Init(); L[now].nxt[tmp]=tot; } now=L[now].nxt[tmp]; } L[now].ed++; //单词结尾 } void build(){ queue<int>q; int now=0; fail[now]=now; for(int i=0;i<26;i++){ //第1次循环时处理与root相连的字符,因为第一个字符不匹配需要重新匹配,所以第一个字符都指向root if(L[now].nxt[i]==-1) L[now].nxt[i]=now; else{ fail[L[now].nxt[i]]=now; q.push(L[now].nxt[i]); //如果存在则入队 } } while(!q.empty()){ now=q.front(); q.pop(); for(int i=0;i<26;i++){ if(L[now].nxt[i]==-1) //如果now下面没有该字符,则重新匹配 L[now].nxt[i]=L[fail[now]].nxt[i]; else{ //如果now下面有该字符,该字符的重新匹配应指向now重新匹配的下面一个字符,并且把该字符入队 fail[L[now].nxt[i]]=L[fail[now]].nxt[i]; q.push(L[now].nxt[i]); } } } } int query(){ int len=strlen(st),now=0,tmp,ret=0; for(int i=0;i<len;i++){ now=L[now].nxt[st[i]-'a']; tmp=now; while(tmp){ //如果tmp变成root则退出循环 ret+=L[tmp].ed; //如果此处为某个单词的结尾,则加上在此结尾的单词数 L[tmp].ed=0; //加完后标记为0,避免重复 tmp=fail[tmp]; //搜索下一个重新匹配 } } return ret; } int main(){ int T; // freopen("in.txt","r",stdin); scanf("%d",&T); while(T--){ int n; tot=0; L[0].Init(); //每次要把root初始化 scanf("%d",&n); while(n--){ scanf("%s",st); add(); } build(); scanf("%s",st); printf("%d\n",query()); } return 0; }
相关文章推荐
- 纯虚函数 & 实例化
- SpringBoot开发实践-起步
- tjut 4912
- [置顶] 实践篇之论机器人的环境感知与智主运动
- 使用Spring的Log4jConfigListener动态加载log4j
- 死锁和避免出现死锁的方式
- HTML5(七)表格-table标签、tr标签、td标签
- maven常用命令
- Chrome开发者工具中关于“Deferred long-running timer task(s) ”的警告
- HDU 1598 find the most comfortable road 并查集+贪心
- 乱头发节(badhair)
- 华为手机不兼容URI的使用问题
- (8)HTML标签详解之<meta>
- 客户反映个人网站服务器慢,作为管理者如何排错解决?
- html5新标签dataList
- python 8位随机密码脚本
- web.xml中webAppRootKey
- BZOJ1603 NOI2008 设计路线 树形dp
- android垃圾回收机制及程序优化System.gc
- 线段树求逆序数