|算法讨论|AC自动机 学习笔记
来源:互联网 发布:37传奇霸业网络异常 编辑:程序博客网 时间:2024/06/06 08:43
题目
[AC自动机]Hdu 2222:裸的AC自动机
模板及讲解
在学习AC自动机之前需要熟练掌握WA自动机、RE自动机与TLE自动机
//伪代码(仅主题部分)procedure find(char *s)begin //枚举匹配文本的每个字符 for i = 1 -> strlen(s) do j <- ch[j][c] //其中c是s[i]-'a' if val[j] then dosomething(j) else if last[j] then dosomething(last[j]) endforendprocedure getfail()begin //初始化入队 for c = 0 -> _SIZE-1 do u <- ch[0][c] if u then 入队,初始化last和f endfor while 队列不空 do r <- 队首 for c = 0 -> _SIZE-1 do u <- ch[0][c] if !u then ch[r][c] <- ch[f[r]][c] 进队u 沿着失配边走直到可以匹配后,求出last和f的值 endfor endwhileend
模板题:Hdu 2222 Keywords Search,解决先给出关键字后,再给出寻找文本进行匹配问题
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #define ms(i,j) memset(i,j, sizeof i); using namespace std;const int MAXN = 10000 + 5, _SIZE = 26; int n;struct acam{ int sz;//结点编号 int res; int ch[MAXN*51][_SIZE];//Tire int last[MAXN*51];//后缀链接 int f[MAXN*51];//失配函数 int val[MAXN*51][2];//结点的权值 bool used[MAXN*51];//用过 void init()//初始化 { ms(val,0); ms(ch,0); ms(used,false); sz = 1; res = 0; } void insert(char *s, int v)//插入一个模板 { int u = 0; int len = strlen(s); for (int i=0;i<len;i++) { int c = s[i] - 'a'; if (ch[u][c]) { u = ch[u][c]; } else { ch[u][c] = ++sz; u = ch[u][c]; } if (i==len-1) { val[u][0] = v; val[u][1]++; } } } void g(int j)//递归更新cnt { if (j&&!used[val[j][0]]) { res+=val[j][1]; used[val[j][0]] = true; g(last[j]); } } void find(char *T)//在T中匹配 { int len = strlen(T); int j = 0; for (int i=0;i<len;i++) { int c = T[i] - 'a'; j = ch[j][c]; if (val[j][0]) g(j); else if (last[j]) g(last[j]); } } void getFail()//获得失配函数 { queue<int> q; f[0] = 0; for (int c=0;c<_SIZE;c++)//初始化进队 { int u = ch[0][c]; if (u) { q.push(u); f[u] = 0; last[u] = 0; } } while (!q.empty()) { int r = q.front(); q.pop(); for (int c=0;c<_SIZE;c++) { int u = ch[r][c]; if (!u) { ch[r][c] = ch[f[r]][c]; continue; } q.push(u); int j = f[r]; while (j&&!ch[j][c]) j = f[j]; f[u] = ch[j][c]; last[u] = (val[f[u]][0]) ? (f[u]) : (last[f[u]]); } } } }ac;char s[1000000 + 5];int main() { int kase; scanf("%d", &kase); while (kase--) { ac.init(); scanf("%d", &n); for (int i=1;i<=n;i++) { scanf("%s", s); ac.insert(s,i); } scanf("%s", s); ac.getFail(); ac.find(s); printf("%d\n", ac.res); } return 0; }
0 0
- |算法讨论|AC自动机 学习笔记
- AC自动机算法笔记
- AC自动机学习笔记
- AC自动机学习笔记
- 学习笔记:AC自动机
- AC自动机 学习笔记
- AC自动机学习笔记
- AC自动机跟随Kuangbing学习笔记
- AC自动机——学习笔记
- AC自动机算法与AC自动机专辑
- AC自动机算法与AC自动机专辑
- AC自动机算法
- AC自动机算法详解
- AC自动机算法详解
- AC自动机算法详解
- AC自动机算法
- AC自动机算法详解
- AC自动机算法详解
- ffmpeg 和 x264的参数对照
- ButterKnife8.5.1最新版本使用详细步骤
- 11. Container With Most Water
- 自定义注解
- java-基础 如何查询java的版本
- |算法讨论|AC自动机 学习笔记
- windows 安装Zookeeper
- The Unreasonable Effectiveness of Recurrent Neural Networks
- 注解TXT
- thinkphp3.2.3 临时表数据操作
- 微信群控系统的作用
- Spring在工具类中使用注解注入Bean
- 什么是企业门户?一句话跟您说清楚。
- 【JAVA SE】6.程序格式+运算符