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

总时间限制: 
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 }



猜你喜欢

转载自www.cnblogs.com/Jeffrey-Y/p/10223993.html