zoukankan      html  css  js  c++  java
  • Match:Keywords Search(AC自动机模板)(HDU 2222)

                    

                      多模匹配

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

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

      

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <functional>
      4 #include <string.h>
      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
    ", 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] != ''; 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] != ''; 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 }

      

  • 相关阅读:
    LeetCode 231. 2的幂
    LeetCode 50. Pow(x, n)
    LeetCode 80. 删除有序数组中的重复项 II
    LeetCode 26. 删除有序数组中的重复项
    LeetCode 88. 合并两个有序数组
    LeetCode 781. 森林中的兔子
    在linux下使用 Fitilink 3D Webcam (18e3:5031)
    ros tf2使用示例
    使用QtCreator作为ROS调试器
    linux基于file的logger
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5185793.html
Copyright © 2011-2022 走看看