多模式串字符串匹配模板题

总时间限制: 
1000ms

内存限制: 
65536kB
描述

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

输入
第一行是整数n,表示有n个模式串 ( n <= 1000)
接下来n行每行一个模式串。每个模式串长度不超过20
接下来一行是整数m,表示有m个句子 (m <= 1000)
接下来m行,每行一个句子,每个句子长度不超过1000
输出
对每个句子,如果包含某个模式串,则输出 YES, 否则输出 NO
样例输入
3
abc
def
gh
2
abcd
ak
样例输出
YES
NO
 1 #include <iostream>
 2 #include <cstring>
 3 #include <deque>
 4 using namespace std;
 5
 6 const int maxN = 1005;
 7 const int maxM = 1005;
 8 const int LETTERS = 26;
 9
10 struct CNode
11 {
12     CNode *pChilds[LETTERS];
13     CNode *pPrev;
14     bool bBadNode;
15     CNode(){
16         memset(pChilds, 0, sizeof(pChilds));
17         pPrev = NULL;
18         bBadNode = false;
19     }
20 }Tree[30000];
21
22 int N, M, nNodesCount;               /* N pattern strings and M sentences */
23 char patternStr[maxN];
24
25 void Insert(CNode* pRoot, char *s)
26 {
27     for (int i = 0; s[i]; i++){
28         if (!pRoot->pChilds[s[i] - ‘a‘]) {
29             pRoot->pChilds[s[i] - ‘a‘] = Tree + nNodesCount;
30             nNodesCount++;
31         }
32         pRoot = pRoot->pChilds[s[i] - ‘a‘];
33     }
34     pRoot->bBadNode = true;
35 }
36
37 void BuildDfa()
38 {
39     for (int i = 0; i < LETTERS; i++)
40         Tree[0].pChilds[i] = Tree + 1;
41     Tree[0].pPrev = NULL;
42     Tree[1].pPrev = Tree;
43     deque<CNode *> q;
44     q.push_back(Tree + 1);
45     while (!q.empty()) {
46         CNode *pRoot = q.front();
47         q.pop_front();
48         for (int i = 0; i < LETTERS; i++) {
49             CNode *p = pRoot->pChilds[i];
50             if (p) {
51                 CNode *pPrev = pRoot->pPrev;
52                 while (!pPrev->pChilds[i])
53                     pPrev = pPrev->pPrev;
54                 p->pPrev = pPrev->pChilds[i];
55                 if (p->pPrev->bBadNode)
56                     p->bBadNode = true;
57                 q.push_back(p);
58             }
59         }
60     }
61 }
62
63 bool SearchDfa(char *s)
64 {
65     CNode *p = Tree + 1;
66     for (int i = 0; s[i]; i++) {
67         while (!p->pChilds[s[i] - ‘a‘])
68             p = p->pPrev;
69         p = p->pChilds[s[i] - ‘a‘];
70         if (p->bBadNode) return true;
71     }
72     return false;
73 }
74
75 int main()
76 {
77     char s[maxN];
78     nNodesCount = 2;
79
80     cin >> N;
81     for (int i = 0; i < N; i++) {
82         cin >> patternStr;
83         Insert(Tree + 1, patternStr);
84     }
85
86     BuildDfa();
87
88     cin >> M;
89     for (int i = 0; i < M; i++){
90         cin >> s;
91         if (SearchDfa(s)) printf("YES\n");
92         else printf("NO\n");
93     }
94
95     //system("pause");
96     return 0;
97 }

原文地址:https://www.cnblogs.com/Jeffrey-Y/p/10223993.html

时间: 2024-08-02 00:05:48

多模式串字符串匹配模板题的相关文章

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

hdu5384 AC自动机模板题,统计模式串在给定串中出现的个数

http://acm.hdu.edu.cn/showproblem.php?pid=5384 Problem Description Danganronpa is a video game franchise created and developed by Spike Chunsoft, the series' name is compounded from the Japanese words for "bullet" (dangan) and "refutation&q

【基本算法】 KMP文本串模式串的字符串匹配算法

看了两个晚上的KMP,加上基本的“暴力匹配” 今晚看懂next[j]递归求解时,突然觉得算法真的好美妙,虽然觉悟的晚但晚胜过没有是吧! 我的博客都是应试性的学习笔记,不具备指导性,还是大神们写的好,例如July和matrix67的博客(今天还知道了matrix67的传奇) [置顶] 从头到尾彻底理解KMP(2014年8月22日版) [置顶]         从头到尾彻底理解KMP(2014年8月22日版) 实习辞职了,可以全心全意看书找工作了,自由真是好!!为了我们俩以后在一起!! 什么时候努力

hdu2896 病毒侵袭 AC自动机入门题 N(N &lt;= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M &lt;= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串,

/** 题目:hdu2896 病毒侵袭 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:N(N <= 500)个长度不大于200的模式串(保证所有的模式串都不相同), M(M <= 1000)个长度不大于10000的待匹配串,问待匹配串中有哪几个模式串, 题目保证每个待匹配串中最多有三个模式串. 思路:ac自动机做法,字符为可见字符,那么直接就是他们的ascii值作为每一个字符的标志.最多128: 由于不超过三个,所以找到3个就可以re

hdu3065 病毒侵袭持续中 AC自动机入门题 N(N &lt;= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数。

/** 题目:hdu3065 病毒侵袭持续中 链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065 题意:N(N <= 1000)个长度不大于50的模式串(保证所有的模式串都不相同), 一个长度不大于2000000的待匹配串,求模式串在待匹配串中的出现次数. 思路:ac自动机做发,val标记每一个病毒串编号,通过print函数统计每一个病毒出现的次数. AC自动机好文章:http://www.cppblog.com/menjitianya/archi

(KMP 1.6)hdu 2203 亲和串(判断文本串循环移位之后是否能将模式串包含在其中)

题目: 亲和串 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9139    Accepted Submission(s): 4174 Problem Description 人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,

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

一.构建步骤 1.将所有模式串构建成 Trie 树 2.对 Trie 上所有节点构建前缀指针(类似kmp中的next数组) 3.利用前缀指针对主串进行匹配 AC自动机关键点一:trie字典树的构建过程 字典树的构建过程是这样的,当要插入许多单词的时候,我们要从前往后遍历整个字符串, 当我们发现当前要插入的字符其节点再先前已经建成,我们直接去考虑下一个字符即可, 当我们发现当前要插入的字符没有再其前一个字符所形成的树下没有自己的节点, 我们就要创建一个新节点来表示这个字符,接下往下遍历其他的字符.

CSU2004:Finding words(含指定不相交前后缀的模式串计数)

题:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2004 题意:给定n个模式串,m个询问,每个询问是“前缀+‘*’+后缀 ”的组合的串S,输出n个模式串中有几个和S是相同的,‘*’可以是0和或更多的字符组成 分析:一般是用给定的模式串来减trie图,但这题显然比较困难,解不出,那么就考虑反过来,我们拿询问的字符串进行构建: 这里要做一下处理:以“后缀+’z+1‘+前缀”地插入trie图,z+1用来代替特殊字符: 因为题目要求的是类似断开的

【算法】AC自动机/AC算法 - 多模式串快速匹配

AC自动机 Accepted Aho-Corasick 性质 AC自动机/AC算法(Aho-Corasick automaton),是著名的多模式串匹配算法. 前置知识 字典树(重要) KMP算法(了解Next数组的作用) 典例与算法复杂度分析 典型例题是:给定一个主串 S,给定多个模式串 T,问主串 S 中存在多少个给定的模式串 在KMP算法中,一个长度为n的主串一个长度为m的模式串的复杂度为 O(n+m) 而如果直接照搬KMP算法到这种题型下,模式串处理一次就需要匹配一次 如果有t个模式串,