Day 2 整理
来源:互联网 发布:手机淘宝卖家中心网址 编辑:程序博客网 时间:2024/06/08 10:37
AC自动机
KMP在Trie上的完美运用,在Trie树上构建fail指针
AC自动机的构造:
1.构造一棵Trie,作为AC自动机的搜索数据结构。
2.构造fail指针,使当前字符失配时跳转到具有最长公共前后缀的字符继续匹配。如同 KMP算法一样, AC自动机在匹配时如果当前字符匹配失败,那么利用fail指针进行跳转。由此可知如果跳转,跳转后的串的前缀,必为跳转前的模式串的后缀并且跳转的新位置的深度(匹配字符个数)一定小于跳之前的节点。所以我们可以利用 bfs在 Trie上面进行 fail指针的求解。
3.扫描主串进行匹配。
后缀数组:
#define rep(i,n) for(int i = 0;i < n; i++)using namespace std;const int size = 200005,INF = 1<<30;int rk[size],sa[size],height[size],w[size],wa[size],res[size];void getSa (int len,int up) { int *k = rk,*id = height,*r = res, *cnt = wa; rep(i,up) cnt[i] = 0; rep(i,len) cnt[k[i] = w[i]]++; rep(i,up) cnt[i+1] += cnt[i]; for(int i = len - 1; i >= 0; i--) { sa[--cnt[k[i]]] = i; } int d = 1,p = 0; while(p < len){ for(int i = len - d; i < len; i++) id[p++] = i; rep(i,len) if(sa[i] >= d) id[p++] = sa[i] - d; rep(i,len) r[i] = k[id[i]]; rep(i,up) cnt[i] = 0; rep(i,len) cnt[r[i]]++; rep(i,up) cnt[i+1] += cnt[i]; for(int i = len - 1; i >= 0; i--) { sa[--cnt[r[i]]] = id[i]; } swap(k,r); p = 0; k[sa[0]] = p++; rep(i,len-1) { if(sa[i]+d < len && sa[i+1]+d <len &&r[sa[i]] == r[sa[i+1]]&& r[sa[i]+d] == r[sa[i+1]+d]) k[sa[i+1]] = p - 1; else k[sa[i+1]] = p++; } if(p >= len) return ; d *= 2,up = p, p = 0; }}void getHeight(int len) { rep(i,len) rk[sa[i]] = i; height[0] = 0; for(int i = 0,p = 0; i < len - 1; i++) { int j = sa[rk[i]-1]; while(i+p < len&& j+p < len&& w[i+p] == w[j+p]) { p++; } height[rk[i]] = p; p = max(0,p - 1); }}int getSuffix(char s[]) { int len = strlen(s),up = 0; for(int i = 0; i < len; i++) { w[i] = s[i]; up = max(up,w[i]); } w[len++] = 0; getSa(len,up+1); getHeight(len); return len;}
我原来好像好写过一篇后缀数组基于sort的博客,但是就是比较慢一点(也不会差太多,常数级别)
贴一下吧:
int n,k,rank[maxn],tmp[maxn];bool compare_sa(int i,int j){ if(rank[i]!=ramk[j]) return rank[i] < rank[j]; else{ int ri = i+k <= n ? rank[i+k] : -1; int rj = j+k <= n ? rank[j+k] : -1; return ri < rj; }}void construct_sa(string s,int *sa){ n = s.length(); for(int i=0;i<=n;i++){ sa[i]=i; rank[i]= i < n ? s[i] : -1; } for(int k=1; k<=n;k*=2){ sort(sa,sa+n+1,compare_sa); tmp[sa[0]]=0; for(int i=1;i<=n;i++){ tmp[sa[i]] = tmp[sa[i-1]] + (sonpare_sa(sa[i-1],sa[i]) ? 1 : 0); } for(int i=0;i<=n;i++){ rank[i]=tmp[i]; } }}
0 0
- Day 2 整理
- 【整理向】Symfony2 Jobeet Day 2: The Project
- Unreal Open Day 2017整理
- DAY 2
- Day-2
- Day-2
- DAY 2
- day 2
- day 2
- Day-2
- DAY-2
- Day 2
- 0day软件整理【使用工具】
- National Day log 2
- Friday Away Day 2
- 2nd Day
- Oracle10g 2day dba
- WinHEC&MEDC Day 2
- 剑指offer------两个链表的第一个公共节点
- LeetCode 3. Longest Substring Without Repeating Characters
- spring中InitializingBean接口使用理解
- 1.2.ARM裸机第二部分-ARM体系结构与汇编指令
- JavaScript对象---Date
- Day 2 整理
- 一周搞定MPU6050Linux驱动(1)
- DP一周总结
- 【学习笔记13】java面向对象-强制类型转换
- [实训]解决eclipse中git push一直需要输入远程push地址的问题
- 通过反射操作类方法,类的成员变量
- Mac virtualenv创建新环境报错
- 多显卡问题
- web.xml <async-supported>true</async-supported>报错