码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-10-30 00:21:52      阅读:294      评论:0      收藏:0      [点我收藏+]

标签:arch   none   scanf   判断   scan   using   math.h   整数   names   

描述

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

输入第一行是整数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] != \0; i++) {
56         while (first->next[str[i]-a] == NULL) 
57             first = first->prev;
58         if (first->next[str[i]-a]->isdanger) {
59             printf("YES\n");
60             return;
61         }
62         first = first->next[str[i] - a];
63     }
64     printf("NO\n");
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自动机

标签:arch   none   scanf   判断   scan   using   math.h   整数   names   

原文地址:https://www.cnblogs.com/yalphait/p/9874009.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!