AC自动机模版
来源:互联网 发布:大数据对银行业的影响 编辑:程序博客网 时间:2024/05/16 13:52
Trie树上的前缀指针:假设有一个节点k,他的前缀指针指向j。那么k,j满足这个性质:设root到j的距离为n,则从k之上的第n个节点到k所组成的长度为n的单词,与从root到j所组成的单词相同。
如何构建前缀指针:根据KMP的启发
root及其儿子的前缀指针指向root
对于每个节点:设这个节点上的字母为C,沿着他父亲的前缀指针遍历,直到访问到一个节点,他的儿子中也有字母为C的节点。然后把当前节点的前缀指针指向那个字母也为C的儿子。如果一直走到了root都没找到,那就把前缀指针指向root(可以看做遍历了多个Trie的next数组)
对于Tire树的每个结点,我们都要求生成其前缀指针
顺序问题:在生成一个结点的前缀指针,需要其父亲的前缀指针,以及这个指针指向的结点的前缀指针等等。这些前缀指针所在结点的深度都不可能比当前结点深,所以生成前缀指针采用BFS遍历字典树
如何构建前缀指针:根据KMP的启发
root及其儿子的前缀指针指向root
对于每个节点:设这个节点上的字母为C,沿着他父亲的前缀指针遍历,直到访问到一个节点,他的儿子中也有字母为C的节点。然后把当前节点的前缀指针指向那个字母也为C的儿子。如果一直走到了root都没找到,那就把前缀指针指向root(可以看做遍历了多个Trie的next数组)
对于Tire树的每个结点,我们都要求生成其前缀指针
顺序问题:在生成一个结点的前缀指针,需要其父亲的前缀指针,以及这个指针指向的结点的前缀指针等等。这些前缀指针所在结点的深度都不可能比当前结点深,所以生成前缀指针采用BFS遍历字典树
#include <cstdio>#include <iostream>#include <cstring>#include <queue>using namespace std;#define maxn 11000char a[101], b[101];int t, n, ans;struct Tnode{ Tnode *next[26], *fail; int cnt; Tnode() { cnt = 0; for (int i = 0;i < 26;i++) next[i] = NULL; fail = NULL; }}*root;void insert(char *s)//构建字典树;{ Tnode *p = root; int i, len = strlen(s); for (i = 0;i < len;i++) { if (p->next[s[i] - 'a'] == NULL) p->next[s[i] - 'a'] = new Tnode(); p = p->next[s[i] - 'a']; } p->cnt = p->cnt + 1;//个数;}void build()//构建失败指针,利用bfs;{ int i, j; root->fail = root; queue<Tnode*> Q;// queue<Tnode*>Q; for (i = 0;i < 26;i++) { if (root->next[i] != NULL) { root->next[i]->fail = root; Q.push(root->next[i]);//queue[rear++] = root->next[i]; } } while (!Q.empty()) { Tnode *p = Q.front(); Q.pop(); for (i = 0;i < 26;i++) { if (p->next[i] == NULL) continue; Q.push(p->next[i]); Tnode *q = p->fail; while (q->next[i] == NULL && q != root) q = q->fail; if (q->next[i] != NULL) p->next[i]->fail = q->next[i]; else p->next[i]->fail = root; } } return;}void query(char *s){ int len = strlen(s), i; Tnode *p = root; for (i = 0;i < len;i++) { while (p->next[s[i] - 'a'] == NULL && p != root) p = p->fail; if (p->next[s[i] - 'a'] != NULL) p = p->next[s[i] - 'a']; Tnode *q = p; while (q != root) { ans += q->cnt; q->cnt = 0;//以免重复计算; q = q->fail; } } return;}int main(){ int i, j; scanf ("%d", &t); while (t--) { ans = 0; root = new Tnode(); scanf ("%d", &n); getchar(); for (i = 0;i < n;i++) { gets(a); insert(a); } build(); gets(b); query(b); printf ("%d\n", ans); } return 0;}
1 0
- hdu2222 ac自动机模版
- AC自动机模版
- AC自动机模版
- AC自动机模版
- AC自动机模版
- ac自动机模版hdu2222
- hdu2222 ac自动机模版
- AC自动机模版
- ac自动机模版
- HDOJ2222 AC自动机模版题
- hdu 2222 ac自动机模版
- HDU 2222 AC自动机模版
- Trie树,AC自动机模版
- LA4670 AC自动机模版题
- HDU 5384 AC自动机模版
- ac自动机模版(hdu 5384)
- HDU 2222 AC自动机模版题
- hdu 2896 AC自动机模版题
- 孫抃 (逸話)
- HDU1548-A strange lift【广搜做法】
- hdu 3183 A Magic Lamp(RMQ)
- 高级数据结构及算法分类
- uva10401Injured Queen Problem(递推)
- AC自动机模版
- K2 blackpearl 中的业务规则(Rules)
- 如何通过文本框导航
- 【面试准备】数据结构—树
- 基于CC2530的ZigBee转以太网网关的设计与实现
- 你在烦恼什么
- 链接,转载与库:关于程序装载入内存的一些小实验
- ibatis中传递多个参数
- 珠海SEO 告诉你如何聘请好的SEO公司