• HDU 2896 病毒侵袭(AC自动机)


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

    题意:给你n个模式串,m个主串,求出每个主串中出现的模式串的标号。

    思路:AC自动机水题,trie树中维护标号,m次扫描即可,注意点输出格式。

    code:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <set>
      5 using namespace std;
      6 const int MAXN = 10005;
      7 const int KIND = 128;
      8 
      9 struct node
     10 {
     11     int id;
     12     node* fail;
     13     node* next[KIND];
     14     node()
     15     {
     16         id = 0;
     17         fail = NULL;
     18         for (int i = 0; i < KIND; ++i) next[i] = NULL;
     19     }
     20 };
     21 node* root;
     22 int L = 0;
     23 char str[MAXN];
     24 set<int> ans;
     25 
     26 void Insert(char str[])
     27 {
     28     node* temp = root;
     29     int len = strlen(str);
     30     for (int i = 0; i < len; ++i)
     31     {
     32         if (temp->next[str[i]] == NULL)
     33             temp->next[str[i]] = new node();
     34         temp = temp->next[str[i]];
     35     }
     36     temp->id = ++L;
     37 }
     38 
     39 void Build()
     40 {
     41     queue<node*>Q;
     42     root->fail = root;
     43     for (int i = 0; i < KIND; ++i)
     44     {
     45         if (root->next[i] == NULL)
     46             root->next[i] = root;
     47         else
     48         {
     49             root->next[i]->fail = root;
     50             Q.push(root->next[i]);
     51         }
     52     }
     53     while (!Q.empty())
     54     {
     55         node* temp = Q.front();
     56         Q.pop();
     57         for (int i = 0; i < KIND; ++i)
     58         {
     59             if (temp->next[i] == NULL)
     60                 temp->next[i] = temp->fail->next[i];
     61             else
     62             {
     63                 temp->next[i]->fail = temp->fail->next[i];
     64                 Q.push(temp->next[i]);
     65             }
     66         }
     67     }
     68 }
     69 
     70 int Query(char str[])
     71 {
     72     node* temp = root;
     73     int len = strlen(str);
     74     ans.clear();
     75     for (int i = 0; i < len; ++i)
     76     {
     77         while (temp->next[str[i]] == NULL && temp != root) temp = temp->fail;
     78         temp = temp->next[str[i]];
     79         if (temp == NULL) temp = root;
     80         node* x = temp;
     81         while (x != root)
     82         {
     83             if (x->id != 0) ans.insert(x->id);
     84             x = x->fail;
     85         }
     86     }
     87     return ans.size();
     88 }
     89 
     90 
     91 int main()
     92 {
     93     int n, m;
     94     int tot = 0;
     95     while (scanf("%d", &n) != EOF)
     96     {
     97         root = new node();
     98         for (int i = 0; i < n; ++i)
     99         {
    100             scanf("%s", str);
    101             Insert(str);
    102         }
    103         Build();
    104         scanf("%d", &m);
    105         for (int i = 1; i <= m; ++i)
    106         {
    107             scanf("%s", str);
    108             int num = Query(str);
    109             if (num == 0) continue;
    110             printf("web %d:", i);
    111             set<int>::iterator it;
    112             for (it = ans.begin(); it != ans.end(); ++it) printf(" %d", *it);
    113             printf("
    ");
    114             ++tot;
    115         }
    116         printf("total: %d
    ", tot);
    117     }
    118     return 0;
    119 }

     数组实现:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <queue>
      4 #include <set>
      5 using namespace std;
      6 const int KIND = 128;
      7 const int MAXN = 100005;
      8 const int MAXM = 10005;
      9 
     10 struct Trie
     11 {
     12     int next[MAXN][KIND], fail[MAXN], id[MAXN];
     13     int root, L, num;
     14     set<int> ans;
     15     int create()
     16     {
     17         for (int i = 0; i < KIND; ++i)
     18             next[L][i] = -1;
     19         id[L++] = 0;
     20         return L - 1;
     21     }
     22     void init()
     23     {
     24         num = 0;
     25         L = 0;
     26         root = create();
     27     }
     28     void insert(char str[])
     29     {
     30         int now = root;
     31         int len = strlen(str);
     32         for (int i = 0; i < len; ++i)
     33         {
     34             if (-1 == next[now][str[i]])
     35                 next[now][str[i]] = create();
     36             now = next[now][str[i]];
     37         }
     38         id[now] = ++num;
     39     }
     40     void build()
     41     {
     42         queue<int>Q;
     43         fail[root] = root;
     44         for (int i = 0; i < KIND; ++i)
     45         {
     46             if (-1 == next[root][i])
     47                 next[root][i] = root;
     48             else
     49             {
     50                 fail[next[root][i]] = root;
     51                 Q.push(next[root][i]);
     52             }
     53         }
     54         while (!Q.empty())
     55         {
     56             int now = Q.front();
     57             Q.pop();
     58             for (int i = 0; i < KIND; ++i)
     59             {
     60                 if (-1 == next[now][i])
     61                     next[now][i] = next[fail[now]][i];
     62                 else
     63                 {
     64                     fail[next[now][i]] = next[fail[now]][i];
     65                     Q.push(next[now][i]);
     66                 }
     67             }
     68         }
     69     }
     70     int query(char str[])
     71     {
     72         ans.clear();
     73         int now = root;
     74         int len = strlen(str);
     75         for (int i = 0; i < len; ++i)
     76         {
     77             now = next[now][str[i]];
     78             int temp = now;
     79             while (temp != root)
     80             {
     81                 if (id[temp]) ans.insert(id[temp]);
     82                 temp = fail[temp];
     83             }
     84         }
     85         return (int)ans.size();
     86     }
     87 };
     88 Trie ac;
     89 char str[MAXM];
     90 int main()
     91 {
     92     int n, m, tot;
     93     while (scanf("%d", &n) != EOF)
     94     {
     95         ac.init();
     96         tot = 0;
     97         for (int i = 0; i < n; ++i)
     98         {
     99             scanf("%s", str);
    100             ac.insert(str);
    101         }
    102         ac.build();
    103         scanf("%d", &m);
    104         for (int i = 1; i <= m; ++i)
    105         {
    106             scanf("%s", str);
    107             if (0 == ac.query(str)) continue;
    108             printf("web %d:", i);
    109             set<int>::iterator it;
    110             for (it = ac.ans.begin(); it != ac.ans.end(); ++it) printf(" %d", *it);
    111             printf("
    ");
    112             ++tot;
    113         }
    114         printf("total: %d
    ", tot);
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    CPU,MPU,MCU,SOC,SOPC联系与差别
    call && jmp 指令
    认识OD的两种断点
    VB逆向
    ASProtect.SKE.2.11 stolen code解密
    破解之寻找OEP[手动脱壳](2)
    破解之寻找OEP[手动脱壳](1)
    破解常用断点设置
    VB断点大全
    API断点大全
  • 原文地址:https://www.cnblogs.com/ykzou/p/4583547.html
Copyright © 2020-2023  润新知