zoukankan      html  css  js  c++  java
  • 18.10.29 多模式串字符串匹配模板题~AC自动机

    描述

    给若干个模式串,以及若干个句子,判断每个句子里是否包含模式串。 句子和模式串都由小写字母组成

    输入第一行是整数n,表示有n个模式串 ( n <= 1000)
    接下来n行每行一个模式串。每个模式串长度不超过20
    接下来一行是整数m,表示有m个句子 (m <= 1000)
    接下来m行,每行一个句子,每个句子长度不超过1000输出对每个句子,如果包含某个模式串,则输出 YES, 否则输出 NO

    样例输入

    3
    abc
    def
    gh
    2
    abcd
    ak

    样例输出

    YES
    NO

    来源

    Xu Yewen

     1 #include <iostream>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <string>
     6 #include <math.h>
     7 #include <queue>
     8 #include <stdio.h>
     9 #include <string.h>
    10 #include <vector>
    11 #include <fstream>
    12 #include <set>
    13 
    14 using namespace std;
    15 const int maxn = 1005;
    16 char line[maxn];
    17 int m, n,nodecou;
    18 struct node {
    19     node*next[26];
    20     node*prev;
    21     bool isdanger;
    22     node() {
    23         memset(next, 0, sizeof(next));
    24         prev = NULL;
    25         isdanger = false;
    26     }
    27 }tree[maxn*20];
    28 
    29 void build() {
    30     for (int i = 0; i < 26; i++)
    31         tree[0].next[i] = tree + 1;
    32     tree[1].prev = tree;
    33     queue<node*>q;
    34     q.push(tree+1);
    35     while (!q.empty()) {
    36         node*now = q.front();
    37         q.pop();
    38         for (int i = 0; i < 26; i++) {
    39             node*child = now->next[i];
    40             if (child) {
    41                 node*prev = now->prev;
    42                 while (prev->next[i] == NULL)
    43                     prev = prev->prev;
    44                 child->prev = prev->next[i];
    45                 if (prev->isdanger)
    46                     child->isdanger = true;
    47                 q.push(child);
    48             }
    49         }
    50     }
    51 }
    52 
    53 void search(char*str) {
    54     node*first = tree + 1;
    55     for (int i = 0; str[i] != ''; i++) {
    56         while (first->next[str[i]-'a'] == NULL) 
    57             first = first->prev;
    58         if (first->next[str[i]-'a']->isdanger) {
    59             printf("YES
    ");
    60             return;
    61         }
    62         first = first->next[str[i] - 'a'];
    63     }
    64     printf("NO
    ");
    65 }
    66 
    67 void init() {
    68     scanf("%d", &n);
    69     nodecou = 1;
    70     for (int i = 1; i <= n; i++) {
    71         scanf("%s",line);
    72         node *first = tree + 1;
    73         int l = strlen(line);
    74         for (int i = 0; i!=l ; i++) {
    75             if (first->next[line[i] - 'a'] == NULL) {
    76                 nodecou++;
    77                 first->next[line[i] - 'a'] = tree + nodecou;
    78             }
    79             first = first->next[line[i] - 'a'];
    80             if (i == l - 1)
    81                 first->isdanger = true;
    82         }
    83     }
    84     build();
    85     scanf("%d", &m);
    86     while (m--) {
    87         scanf("%s", line);
    88         search(line);
    89     }
    90 }
    91 
    92 int main()
    93 {
    94     init();
    95     return 0;
    96 }
    View Code

    预热题

     1 #include <iostream>
     2 #include <string.h>
     3 #include <algorithm>
     4 #include <stack>
     5 #include <string>
     6 #include <math.h>
     7 #include <queue>
     8 #include <stdio.h>
     9 #include <string.h>
    10 #include <set>
    11 #include <vector>
    12 #define maxn 120005
    13 #define inf 999999
    14 #define EPS 1e-10
    15 #define lowbit(x) (int)(x&(-x))
    16 using namespace std;
    17 
    18 int n, m;
    19 int nodecnt = 1;
    20 struct node {
    21     int next[26];
    22     int prev;
    23     bool badnode;
    24     bool endpoint;
    25     node() {
    26         memset(next, -1, sizeof(next));
    27         prev = -1;
    28         badnode = endpoint = false;
    29     }
    30 }tree[maxn];
    31 char mode[1005];
    32 
    33 void insert() {
    34     int p = 1;
    35     for (int i = 0; mode[i]; i++) {
    36         if (tree[p].next[mode[i] - 'a'] == -1)
    37             tree[p].next[mode[i] - 'a'] = ++nodecnt;
    38         p = tree[p].next[mode[i] - 'a'];
    39     }
    40     tree[p].badnode = true;
    41     tree[p].endpoint = true;
    42 }
    43 
    44 void builddfa() {
    45     deque<int>q;
    46     q.push_back(1);
    47     while (!q.empty()) {
    48         int now = q.front(); q.pop_front();
    49         for (int i = 0; i < 26; i++) {
    50             if (tree[now].next[i] != -1) {
    51                 int prev = tree[now].prev;
    52                 int next = tree[now].next[i];
    53                 while (tree[prev].next[i] == -1)
    54                     prev = tree[prev].prev;
    55                 tree[next].prev = tree[prev].next[i];
    56                 if (tree[prev].badnode)
    57                     tree[next].badnode = true;
    58                 q.push_back(next);
    59             }
    60         }
    61     }
    62 }
    63 
    64 void query() {
    65     int p = 1;
    66     for (int i = 0; mode[i]; i++) {
    67         while (tree[p].next[mode[i] - 'a'] == -1)
    68             p = tree[p].prev;
    69         p = tree[p].next[mode[i] - 'a'];
    70         if (tree[p].badnode) {
    71             printf("YES
    ");
    72             return;
    73         }
    74     }
    75     printf("NO
    ");
    76 }
    77 
    78 void init() {
    79     scanf("%d", &n);
    80     for (int i = 0; i < 26; i++)
    81         tree[0].next[i] = 1;
    82     tree[1].prev = 0;
    83     for (int i = 1; i <= n; i++) {
    84         scanf("%s", mode);
    85         insert();
    86     }
    87     builddfa();
    88     scanf("%d", &m);
    89     while (m--) {
    90         scanf("%s", mode);
    91         query();
    92     }
    93 }
    94 
    95 int main() {
    96     init();
    97     return 0;
    98 }
    View Code

    补上数组做法↑

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    (转)Linux系统调用和库函数调用的区别
    一个“梦想实践重度障碍者”的思考
    按字节输出数据
    内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区[C++][内存管理]
    VimdiffVIM的比较和合并工具
    [每天进步一点 流水账]回顾总结
    计算机就业方向
    ofstream和ifstream详细用法(转)
    ECMAScript 运算符关系运算符
    ECMAScript 语句标签语句
  • 原文地址:https://www.cnblogs.com/yalphait/p/9874009.html
Copyright © 2011-2022 走看看