(AC自动机)模板
2017-08-22 17:20
302 查看
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <queue> using namespace std; const int allSon=26; char patten[60]; ///模式串 char text[1000010]; ///文本串 int ans; struct TrieNode { struct TrieNode *son[allSon]; struct TrieNode *fail;//失败指针 int num;//是不是一个单词 }*root; TrieNode* createNode()//创建Tiree树并且完成对树的初始化 { TrieNode *p; p = (TrieNode*)malloc(sizeof(TrieNode)); memset(p->son,0,sizeof(p->son)); p->num = 0; p->fail = NULL; return p; } ///插入模式串,构建字典树 void insertPatten() { TrieNode *p; p = root; int index = 0; while(patten[index]) { int lowercase = patten[index]-'a'; if(p->son[lowercase]==NULL) { p->son[lowercase] = createNode(); } p = p->son[lowercase]; index++; } p->num++;//到了单词的末尾 此时是一个单词则num置一 } ///求fail指针。构造AC自动机。 void build_AC_automaton()//利用bfs构建失败指针 构建失败指针时需要注意对第二层进行处理 就是让第二层全部都指向根节点 让根节点的失败指针置为ULL { TrieNode *p; p = root; queue<TrieNode*>qu; qu.push(p); while(!qu.empty()) { p = qu.front(); qu.pop(); for(int i = 0; i < allSon; i++) { if(p->son[i] != NULL) ///第i个孩子存在 { if(p == root) ///p是根,根节点的孩子的失败指针都指向自己 { p->son[i]->fail = root; } else { TrieNode *node = p->fail;//如果node不为空 并且在node的儿子里也有字母z让这个失败指针指向失败指针的儿子 while(node != NULL) { if(node->son[i]!=NULL) { p->son[i]->fail = node->son[i]; break; } node = node->fail; } if(node == NULL)//如果到最后都没有找到node里面有字母z则直接让这个失败指针指向其root p->son[i]->fail = root; } qu.push(p->son[i]);//并将其插入队列里面 } } } } void find_in_AC_automaton() { TrieNode *p; p = root; int index = 0; while(text[index] != '\0') { int lowercase = text[index]-'a'; while(p->son[lowercase]==NULL && p!=root) p = p->fail; p = p->son[lowercase]; if(p == NULL) p = root; TrieNode *temp = p; while(temp!=NULL && temp->num!=-1) { ans += temp->num; temp->num = -1; temp = temp->fail; } index++; } } void freeNode(TrieNode *node) { if(node != NULL) { for(int i = 0; i < allSon; i++) freeNode(node->son[i]); } free(node); } int main() { int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); root = createNode(); for(int i = 0; i < n; i++) { scanf("%s",patten); insertPatten(); } scanf("%s",text); build_AC_automaton(); ans = 0; find_in_AC_automaton(); printf("%d\n",ans); freeNode(root); } return 0; }
相关文章推荐
- HDU:2222-Keywords Search(AC自动机模板,匹配模拟)
- 【模板】AC自动机
- AC自动机模板——贴瓷砖
- 【模板】AC自动机
- 数单词 (AC自动机模板题)
- hdu 3065 病毒侵袭持续中(ac自动机模板题)
- HDU 2222 最简单的AC自动机套模板应用
- hdu 2896(AC自动机模板题)
- AC自动机模板 LA4670 Dominating Patterns 出现次数最多的字串 BNUOJ11552 UVA1449
- 关键词匹配(Ac自动机模板题)
- HDU 2222 (AC自动机模板题)
- 邝斌的ACM模板(AC 自动机)
- HDU 2222 Keywords Search (AC自动机模板题)
- HDU 2222 Keywords Search (AC自动机模板题)
- kuangbin专题十七 HDU2896 病毒侵袭(AC自动机模板题)
- ac自动机模板
- 关键词匹配(Ac自动机模板题)
- HDU 2222 Keywords Search(AC自动机模板题)
- HDU3695(AC自动机模板题)
- hdu 5384 Danganronpa(AC自动机模板题)