AC自动机
来源:互联网 发布:gps模拟软件 编辑:程序博客网 时间:2024/05/29 07:13
给定多个模式串,一个目标串,查询模式串在目标串中出现的次数。
暴力,KMP都会超时,于是我们要用一个新的方法,在Trie树上做KMP。
具体的插入和Trie树一致,而多了一个fail数组,其含义和KMP中的失配函数一致。
我们可以通过bfs实现处理每一个点的fail,之后再进行匹配即可。
在树上把路径之和全部相加,所得答案即为出现次数。
#include<cstdio>#include<cstring>#include<queue>using namespace std;const int kind=26;struct node{ node *fail; node *nex[kind]; int cnt; node(){ fail=NULL; cnt=0; memset(nex,NULL,sizeof(nex)); }};inline int idx(char c){return c-'a';}queue<node*> q1;char s[1000005],b[100005];int n;void Insert(char *s,node *root){ int ls=strlen(s); node *p=root; for(int i=0;i<ls;++i){ if(p->nex[idx(s[i])]==NULL) p->nex[idx(s[i])]=new node(); p=p->nex[idx(s[i])]; } p->cnt++;}void build(node *root){ root->fail=NULL; q1.push(root); while(!q1.empty()){ node *tmp=q1.front(),*p=NULL; q1.pop(); for(int i=0;i<26;++i) if(tmp->nex[i]!=NULL){ if(tmp==root) tmp->nex[i]->fail=root; else{ p=tmp->fail; while(p!=NULL){ if(p->nex[i]!=NULL){ tmp->nex[i]->fail=p->nex[i]; break; } p=p->fail; } if(p==NULL) tmp->nex[i]->fail=root; } q1.push(tmp->nex[i]); } }}int query(node *root){ int cnt=0,ls=strlen(s); node *p=root; for(int i=0;i<ls;++i){ while(p->nex[idx(s[i])]==NULL&&p!=root) p=p->fail; p=p->nex[idx(s[i])]; if(p==NULL) p=root; node *tmp=p; while(tmp!=root && tmp->cnt!=-1){ cnt+=tmp->cnt; tmp->cnt=-1; tmp=tmp->fail; } } return cnt;}int main(){ scanf("%s%d",s,&n); node *root=new node(); for(int i=1;i<=n;++i){ scanf("%s",b); Insert(b,root); } build(root); printf("%d",query(root)); return 0;}
阅读全文
0 0
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- activiti个人写的工具类(SpringMVC)
- 公钥密码技术
- 解决 git 无法启动该程序,因为计算机中丢失libiconv-2.dll
- 使用Management Host Control
- Java编程-句子反转
- AC自动机
- gulp常用插件
- java 实现runnable接口与继承Thread类相比的优势
- Tiled地图编辑器使用注意事项
- SecureCRT的Session编码全局设置
- enum的学习运用
- Mysql-锁相关知识
- for in 和 for of的区别
- The C Programming Language 练习题3-4