KMP && AC自动机模板
2015-08-27 23:19
239 查看
KMP:
获得next数组:
KMP匹配:返回母串上与子串匹配的第一个位置的起始处
AC自动机:
获得next数组:
void getNext() { nxt[0] = -1; for(int i = 1; i < n; i++) { int p = nxt[i-1]; for(; p != -1 && str[p+1] != str[i]; p = nxt[p]); p = str[p+1] == str[i] ? p+1 : -1; nxt[i] = p; } }
KMP匹配:返回母串上与子串匹配的第一个位置的起始处
int kmp() { int i = 0, j = 0; for(; i < n; ) { if(str[i] == pat[j]) { i++; j++; if(j == m) return i-m+1; } else { if(j == 0) i++; else { j = nxt[j-1]+1; } } } return -1; }
AC自动机:
class Node { public: int next[30], fail; int endCnt; void clear() { memset(next, 0, sizeof next); endCnt = 0; fail = 0; } }; Node node ; class Trie { public: int root, cnt; void init() { cnt = 0; root = newNode(); node[0].clear(); } int newNode() { node[++cnt].clear(); return cnt; } void ins(char str[], int len) { int p = root; for(int i = 0; i < len; i++) { int cur = str[i]-'A'; if(!node[p].next[cur]) { node[p].next[cur] = newNode(); } p = node[p].next[cur]; } node[p].endCnt++; } void build() { queue<int> q; q.push(root); while(!q.empty()) { int cur = q.front(); q.pop(); for(int i = 0; i < 26; i++) { int nxt = node[cur].next[i]; if(nxt) { int p = node[cur].fail; for(; p != 0 && node[p].next[i] == 0; p = node[p].fail); p = p == 0 ? root : node[p].next[i]; node[nxt].fail = p; q.push(nxt); } } } } int match(char str[], int len) { int p = root, res = 0; for(int i = 0; i < len; i++) { int cur = str[i]-'A'; for(; p && node[p].next[cur] == 0; p = node[p].fail); p = p ? node[p].next[cur] : root; int tp = p; for(; tp && node[tp].endCnt > 0; tp = node[tp].fail) { res += node[tp].endCnt; node[tp].endCnt = 0; } } return res; } };
相关文章推荐
- 2015.8.27
- 线段树 区间修改 总结
- Linux pkg-config命令
- 扩展方法
- Linux splint命令
- Activity的启动模式
- linux下的 fork vfork和clone函数
- 敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则
- STM32 UART DMA实现未知数据长度接收
- iOS GCD多线程介绍
- openssl从PFX导出私钥、公钥
- do...while(0)的妙用
- 一个C语言典型的内存泄露问题
- Backdoor.Win32.Rbot病毒防治
- OC-@property增强使用
- haproxy根据客户端浏览器进行跳转
- Java基础の第一弹
- UIViewController
- 一些简单排序算法的下界
- 安装minGW编译器及其使用方法