UVA1449 AC自动机
来源:互联网 发布:淘宝图片保护怎么弄 编辑:程序博客网 时间:2024/05/16 15:29
给定n个由小写字母组成的字符串和一个文本串T,找出哪些字符串在T中出现的次数最多。
AC自动机应用之一:统计每个模板串在原字符串中出现的次数
AC自动机的精华:利用last函数,将模板串的所有子串连接起来,只要沿着边走就可以遍历所有模板串的所有子串
对于重复的模板串题目要求重复输出,因此需要对每一个字符串对应一个序号,这样相同的字符串可以有两个不同的序号。
#include<cstring>#include<queue>#include<cstdio>#include<map>#include<string>using namespace std;const int SIGMA_SIZE=26;const int MAXNODE=11000;const int MAXS=150+10;map<string,int> ms;struct AC{ int ch[MAXNODE][SIGMA_SIZE]; int f[MAXNODE];//fail函数 int val[MAXNODE];//字符串结尾结点 int last[MAXNODE];//输出链表的下一个节点 int cnt[MAXS]; int sz; void init(){ sz=1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); ms.clear(); } //字符c的编号 int idx(char c){ return c-'a'; } //插入字符串 void insert(char *s,int v){ int u=0,n=strlen(s); for(int i=0;i<n;i++){ int c=idx(s[i]); if(!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=v; ms[string(s)]=v;//记录每个字符串的编号索引 } //递归打印以节点j结尾的所有字符串 //找出所有可以匹配的字符串,“打印”(称为遍历更合适)并计数 void print(int j){ if(j){ cnt[val[j]]++; print(last[j]); } } //在T中找模板 int find(char *T){ int n=strlen(T); int j=0; for(int i=0;i<n;i++){ int c=idx(T[i]); while(j&&!ch[j][c]) j=f[j];//顺着失配边走,直到可以匹配为止 j=ch[j][c]; if(val[j]) print(j); else if(last[j]) print(last[j]);//找到了? } } //计算fail函数 void getfail(){ queue<int> q; f[0]=0; //初始化队列 for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[0][c]; if(u) { f[u]=0;q.push(u);last[u]=0; } } while(!q.empty()){ int r=q.front();q.pop(); for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[r][c]; if(!u) continue; q.push(u); int v=f[r]; while(v&&!ch[v][c]) v=f[v]; f[u]=ch[v][c]; last[u]=val[f[u]]?f[u]:last[f[u]]; } } }};AC ac;char text[1000001],P[151][80];int n,T;int main(){ //freopen("a.txt","r",stdin); while(scanf("%d",&n)!=EOF){ if(!n) break; ac.init(); for(int i=1;i<=n;i++){ scanf("%s",P[i]); ac.insert(P[i],i); } ac.getfail(); scanf("%s",text); ac.find(text); int best=-1; for(int i=1;i<=n;i++) if(ac.cnt[i]>best) best=ac.cnt[i]; printf("%d\n",best); for(int i=1;i<=n;i++) if(ac.cnt[ms[string(P[i])]]==best) printf("%s\n",P[i]); } return 0;}
0 0
- AC自动机+uva1449
- UVA1449 AC自动机
- AC自动机模板 LA4670 Dominating Patterns 出现次数最多的字串 BNUOJ11552 UVA1449
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- svg.draggable.js-实现svg拖拽的js插件
- android wifi 问题定位
- android zygote 到launcher的启动关键点
- Socket编程与线程
- [经典面试题][网易]数组分割
- UVA1449 AC自动机
- Android从系统启动-->Launcher加载-->用户应用开启
- codeforces #247D Random Task (数位dp+二分搜索)
- poj 1703 Find them, Catch them 带权并查集OR种类并查集
- 解决python中用zipfile解压缩文件时中文文件名乱码的问题
- 数组中出现次数超过一半的数字
- 最快最简单的排序——桶排序
- 记录一下linuxmint 17安装搜狗输入法的过程
- 14年的总结与15年的展望