18.10.29 多模式串字符串匹配模板题~AC自动机

Posted yalphait

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

预热题

以上是关于18.10.29 多模式串字符串匹配模板题~AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

hdu2222 Keywords Search(AC自动机初步)

AC自动机

暖*墟 #AC自动机# 多模式串的匹配运用

HDU 2222:Keywords Search(AC自动机模板)

[AC自动机]玄武密码

AC自动机模板