hdu 2222 Keywords Search(AC自动机入门模版题)

来源:互联网 发布:mac eclipse gbk 编辑:程序博客网 时间:2024/06/06 18:20

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222

AC自动机算法:http://blog.csdn.net/niushuai666/article/details/7002823

                          http://www.cnblogs.com/Booble/archive/2010/12/05/1897121.html

                          http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html


#include<iostream>#include<cstdio>#include<cstring>#include<string>using namespace std;#define N 500010char str[1000010], keyword[51];int head, tail;struct node{node *fail;node *next[26];int count;node() //init{fail = NULL;count = 0;for(int i = 0; i < 26; ++i)next[i] = NULL;}}*q[N];node *root;void insert(char *str) //建立Trie{int temp, len;node *p = root;len = strlen(str);for(int i = 0; i < len; ++i){temp = str[i] - 'a';if(p->next[temp] == NULL)p->next[temp] = new node();p = p->next[temp];}p->count++;}void build_ac() //初始化fail指针,BFS{q[tail++] = root;while(head != tail){node *p = q[head++]; //弹出队头node *temp = NULL;for(int i = 0; i < 26; ++i){if(p->next[i] != NULL){if(p == root) //第一个元素fail必指向根p->next[i]->fail = root;else{temp = p->fail; //失败指针while(temp != NULL) //2种情况结束:匹配为空or找到匹配{if(temp->next[i] != NULL) //找到匹配{p->next[i]->fail = temp->next[i];break;}temp = temp->fail;}if(temp == NULL) //为空则从头匹配p->next[i]->fail = root;}q[tail++] = p->next[i]; //入队}}}}int query() //扫描{int index, len, result;node *p = root; //Tire入口result = 0;len = strlen(str);for(int i = 0; i < len; ++i){index = str[i] - 'a';while(p->next[index] == NULL && p != root) //跳转失败指针p = p->fail;p = p->next[index];if(p == NULL)p = root;node *temp = p; //p不动,temp计算后缀串while(temp != root && temp->count != -1){result += temp->count;temp->count = -1;temp = temp->fail;}}return result;}int main(){int T, n;scanf("%d", &T);while(T--){head= tail = 0;root = new node();scanf("%d", &n);getchar();for(int i = 0; i < n; ++i){gets(keyword);insert(keyword);}build_ac();scanf("%s", str);printf("%d\n", query());}return 0;}


0 0
原创粉丝点击