hdu 2222 Keywords Search(AC自动机入门题)
来源:互联网 发布:python读写数据txt 编辑:程序博客网 时间:2024/06/06 19:02
昨晚开始想学AC自动机,然后尽早看了看算导的KMP。。。以前看过,忘差不多了。
今天看了看一个学习AC自动机的文章,磕磕绊绊理解了。
trie的建立很随意,关键是失败指针这个概念。稍微有点抽象。这个指针的建立,用到了BFS,引用那个文章的话
“ 假设有一个节点k,他的失败指针指向j。那么k,j满足这个性质:设root到j的距离为n,则从k之上的第n个节点到k所组成的长度为n的单词,与从root到j所组成的单词相同。对于每个节点,我们可以这样处理:设这个节点上的字母为C,沿着他父亲的失败指针走,直到走到一个节点,他的儿子中也有字母为C的节点。然后把当前节点的失败指针指向那个字目也为C的儿子。如果一直走到了root都没找到,那就把失败指针指向root,最开始,我们把root加入队列(root的失败指针显然指向自己),这以后我们每处理一个点,就把它的所有儿子加入队列,直到搞完。”
查找匹配数目的时候,如果发现不匹配的就沿着失败指针寻找,直到到根部为止。
因为失败指针走一次后再走就没有用了,可以标记下,下次就不用走了。
#include <map>#include <set>#include <queue>#include <stack>#include <math.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define BUG puts("here!!!")#define STOP system("pause")using namespace std;const int MAX_N = 26;const int MAX_NODE = 500010;struct NODE{int cnt;NODE *next[MAX_N], *fail;NODE(){cnt = 0;fail = NULL;memset(next, 0, sizeof(next));}}*head;void Build_trie(char *s,NODE *head){int len = strlen(s);for(int i=0; i<len; i++){int k = s[i] - 'a';if( head->next[k] == NULL )head->next[k] = new NODE();head = head->next[k];}head->cnt++;}queue<NODE*> q;void Build_fail(NODE *head){head->fail = NULL;q.push(head);while( !q.empty() ){NODE *now = q.front(); q.pop();for(int i=0; i<MAX_N; i++)if( now->next[i] ){NODE *p = now->fail;while( p ){if( p->next[i] ){now->next[i]->fail = p->next[i];break;}p = p->fail;}if( p == NULL )now->next[i]->fail = head;q.push(now->next[i]);}}}int AC_find(NODE *head, char *s){int len = strlen(s), sum = 0;NODE* p = head;for(int i=0; i<len; i++){int k = s[i] - 'a';while( p->next[k] == NULL && p != head )p = p->fail;p = p->next[k] == NULL ? head : p->next[k];NODE *tmp = p;while( tmp != head && tmp->cnt != -1 ){sum += tmp->cnt;tmp->cnt = -1;tmp = tmp->fail;}}return sum;}char s[1000005];char ss[100];int main(){int n, ncases;scanf("%d", &ncases);while( ncases-- ){head = new NODE();scanf("%d", &n);while( n-- ){scanf("%s", ss);Build_trie(ss, head);}Build_fail( head );scanf("%s", s);int sum = AC_find( head, s);printf("%d\n", sum);}return 0;}
- hdu 2222 Keywords Search(AC自动机入门题)
- HDU 2222 Keywords Search(AC自动机入门题)
- HDU 2222:Keywords Search(AC自动机入门题)
- hdu 2222 Keywords Search ac自动机入门
- HDU 2222 Keywords Search (AC自动机入门题)
- HDU 2222 Keywords Search AC自动机入门模版题
- HDU 2222 Keywords Search AC自动机入门题
- hdu 2222 Keywords Search (ac自动机入门题)
- hdu 2222 Keywords Search(AC自动机入门模版题)
- hdu 2222 Keywords Search 经典AC自动机入门题
- hdu 2222Keywords Search(AC自动机入门好题)
- HDU-2222 Keywords Search (AC自动机入门题)
- HDU 2222 Keywords Search(AC自动机 入门)
- HDU 2222 Keywords Search (AC 自动机入门)
- hdu 2222 Keywords Search(AC自动机入门)
- HDU-2222 Keywords Search (AC自动机入门)
- HDU 2222 Keywords Search(AC自动机入门,模板)
- hdU 2222 Keywords Search(AC自动机)
- JS 获得 输入框 和 radio 的值
- What Is a SATA Hard Disk?
- 欧拉数e
- Oracle中子查询与Join性能比较
- WEB.XML error-page 配置错误页面
- hdu 2222 Keywords Search(AC自动机入门题)
- 外企面试问题
- 映射模式/视口(viewport)和窗口(window)
- 解决mysql“Access denied for user 'root'@'localhost'”
- eclipse 安装svn插件的几种方式
- 关于.net框架
- Effective STL 摘要
- Bucket_Sort and Radix_Sort
- Eclipse的代码追踪功能