AC自动机模板
2015-03-15 17:36
260 查看
#include <cstdio> #include <algorithm> #include <cmath> #include <queue> #include <algorithm> #define N 500006 using namespace std; char st[1000005]; char keyword[55]; int n,m; int next [26],cnt ,fail ,pos; //初始化字典树的节点 int newNode ( ) { for ( int i = 0; i < 26 ; i++ ) next[pos][i] = 0; fail[pos] = cnt[pos] = 0; return pos++; } //构建字典树 void insert ( char *s ) { int i,p = 0;//p当前为根节点,i为字符串初始位置 for ( i = 0 ; s[i] ; i++ ) { //获得这一字母的节点,如果不存在,创建新的 int k = s[i] -'a' , &x = next[p][k]; p = x?x : x = newnode(); } cnt[p]++; // 位运算要用 } //通过宽搜构建失败指针 void makeNext ( ) { int i; queue<int> q; q.push(0); // 将根节点放入队列中 while ( !q.empty() ) { int u = q.front(); //统计匹配到当前位置能够匹配到的串的个数 cnt[u] += cnt[fail[u]]; q.pop (); for ( int i = 0 ; i < 26 ; i++ ) { int v = next[u][i]; //如果v是0,证明不能匹配,所以通过fail指针找到深度小于当前深度但 //是深度最大的与v和自身的最近公共祖先相邻的与v具有相同字母的节点 //需要通过fail指针跳转过去 if ( v == 0 ) next[u][i] = next[fail[u]][i]; else q.push (v); //否则,要将v推到队列中去,用于宽搜 if ( u && v ) fail[v] = next[fail[u]][i]; } } } int query ( char *s ) { int ret = 0, idx , d = 0; for ( int i = 0; s[i]; i++ ) { idx = s[i] -'a'; d = next[d][idx]; //将当前位置作为串的结尾能匹配到的串的个数 ret += cnt[d]; //将串的个数清0,避免重复统计 cnt[d] = 0; } return ret; }
相关文章推荐
- Match:Keywords Search(AC自动机模板)(HDU 2222)
- hdu 2222(AC自动机模板)
- 模板——AC自动机
- AC自动机模板
- HDU2222 Keywords Search 【AC自动机模板题】
- HDU 2222 Keywords Search(AC自动机模板)
- hdu 1277 全文检索(ac自动机模板)
- HDOJ 2222.Keywords Search(AC自动机模板)
- [AC自动机模板题] HDU 2222 Keywords Search
- AC自动机算法及模板
- AC自动机 ( 模板题啊 )——Dominating Patterns ( UVA 4670 )
- HDU2222 AC自动机 入门模板
- [模板]-AC自动机
- HDU2222 AC自动机模板
- AC自动机模板(hdu2222)
- AC自动机算法及模板
- AC自动机模板
- HDU 2222 ac自动机入门模板题
- HDU2222 Keywords Search(AC自动机模板)
- 【AC自动机】HDU中模板题