博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Match:Keywords Search(AC自动机模板)(HDU 2222)
阅读量:4314 次
发布时间:2019-06-06

本文共 3608 字,大约阅读时间需要 12 分钟。

                

                  

  题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串。

  经典AC自动机模板题,不多说。

  

1 #include 
2 #include
3 #include
4 #include
5 #define MAX 26 6 7 using namespace std; 8 9 struct node 10 { 11 node *fail, *next[MAX]; 12 int count; 13 }Mem_Pool[500001], *Trie_Queue[500001]; 14 static int Used_Node; 15 static char pattern[10001], target[1000001]; 16 17 struct node *Get_New_Node(void); 18 void Insert(struct node*); 19 void Build_AC_Automation(struct node* const); 20 static int Query(struct node* const); 21 22 int main(void) 23 { 24 int case_sum, pattern_sum; 25 scanf("%d", &case_sum); 26 27 while (case_sum--) 28 { 29 Used_Node = 0; 30 node *root = Get_New_Node();//每一次都拿一个新的根 31 scanf("%d", &pattern_sum); 32 getchar(); 33 while (pattern_sum--) 34 Insert(root); 35 Build_AC_Automation(root); 36 gets(target); 37 printf("%d\n", Query(root)); 38 } 39 } 40 41 struct node *Get_New_Node(void) 42 { 43 Mem_Pool[Used_Node].count = 0; 44 Mem_Pool[Used_Node].fail = NULL; 45 memset(Mem_Pool[Used_Node].next, 0, sizeof(struct node *)*MAX); 46 47 return &Mem_Pool[Used_Node++]; 48 } 49 50 void Insert(struct node *root) 51 { 52 gets(pattern); 53 54 node *p = root; 55 int index; 56 for (int i = 0; pattern[i] != '\0'; i++) 57 { 58 index = pattern[i] - 'a'; 59 if (p->next[index] == NULL) 60 p->next[index] = Get_New_Node(); 61 p = p->next[index]; 62 } 63 p->count++;//表示这个位置包含着一个字符,如果有多个则叠加就可以了。 64 } 65 66 void Build_AC_Automation(struct node *const root)//自动机的构造例程,其实就是个BFS 67 { 68 root->fail = NULL; 69 int head = 0, back = 0; 70 node *out = NULL, *tmp = NULL; 71 Trie_Queue[back++] = root; 72 73 while (head != back) 74 { 75 out = Trie_Queue[head++]; 76 for (int i = 0; i < MAX; i++)//枚举所有情况 77 if (out->next[i] != NULL) 78 { 79 if (out == root) 80 out->next[i]->fail = root;//如果out自己就是根,那么直接将其子节点的失败指针指向自己就好了 81 else 82 { 83 for (tmp = out->fail; tmp != NULL; tmp = tmp->fail) 84 if (tmp->next[i] != NULL) 85 { 86 out->next[i]->fail = tmp->next[i]; 87 //如果还找到在其他地方找到和他一样的元素,那么我们就把失败指针指向这个元素 88 break; 89 } 90 if (tmp == NULL) 91 out->next[i]->fail = root; 92 } 93 Trie_Queue[back++] = out->next[i]; 94 } 95 } 96 } 97 98 static int Query(struct node *const root) 99 {100 int ans = 0;101 node *tmp = root, *other = NULL;102 //tmp是跟着目标串的移动而移动的,other指针则表示在tire树的其他位置看还能不能匹配到其他字串103 for (int i = 0; target[i] != '\0'; i++)104 {105 int index = target[i] - 'a';106 while (tmp->next[index] == NULL && tmp != root)107 tmp = tmp->fail;//沿着失败指针一直走108 tmp = tmp->next[index];109 tmp = (tmp == NULL) ? root : tmp;//检查如果是已经是root了,直接跳出来就好了110 for (other = tmp; other != root && other->count != -1; other = other->fail)111 {112 ans += other->count;113 other->count = -1;//标记一下,不要重复扫描114 }115 }116 return ans;117 }

  

转载于:https://www.cnblogs.com/Philip-Tell-Truth/p/5185793.html

你可能感兴趣的文章
0007_初始模块和字节码
查看>>
[效率提升]如何管理好你的电脑文件
查看>>
C++实验二
查看>>
SharePoint2010 富文本框添加图片功能的扩展
查看>>
零零碎碎的知识
查看>>
UNIX基础--用户和基本账户管理
查看>>
设计模式
查看>>
5.0以上机器XPOSED框架安装流程
查看>>
静态方法与非静态方法
查看>>
注释,字符串
查看>>
性能瓶颈
查看>>
cmd 导入数据库
查看>>
Makefile书写注意事项--个人择记(一)
查看>>
文件转码重写到其他文件
查看>>
场景3 Data Management
查看>>
树结构练习——排序二叉树的中序遍历
查看>>
AC自动机模板
查看>>
python 基本语法
查看>>
Swift - 点击箭头旋转
查看>>
git配置
查看>>