描述
給若干個模式串,以及若干個句子,判斷每個句子裏是否包含模式串。 句子和模式串都由小寫字母組成
輸入
第一行是整數n,表示有n個模式串 ( n <= 1000)
接下來n行每行一個模式串。每個模式串長度不超過120
接下來一行是整數m,表示有m個句子 (m <= 1000)
接下來m行,每行一個句子,每個句子長度不超過1000
輸出
對每個句子,如果包含某個模式串,則輸出 YES, 否則輸出 NO
樣例輸入
3
abc
def
gh
2
abcd
ak
樣例輸出
YES
NO
#include<iostream>
#include<deque>
#include<cstring>
#include<algorithm>
using namespace std;
int nums = 0;
const int letters = 26;
char s[200];
struct node
{
node *childs[letters];
node *pre;
bool badnode;
node()
{
memset(childs, 0, sizeof(childs));
pre = NULL;
badnode = false;
}
} tree[120000];
void insert(node* now)
{
for (int i = 0; s[i]; i++)
{
if(now->childs[s[i] - 'a'] == NULL)
{
now->childs[s[i] - 'a'] = tree + nums;
nums++;
}
now = now->childs[s[i] - 'a'];
}
now->badnode = 1;
}
void build_dfa()
{
for (int i = 0; i < letters;i++)
{
tree[0].childs[i] = tree + 1;
}
tree[0].pre = NULL;
tree[1].pre = tree;
deque<node *> q;
q.push_back(tree + 1);
while(!q.empty())
{
node *now = q.front();
q.pop_front();
for (int i = 0; i < letters;i++)
{
node *p = now->childs[i];
if(p)
{
node *pre = now->pre;
while(pre->childs[i]==NULL)
{
pre = pre->pre;
}
p->pre = pre->childs[i];
if(pre->badnode)
p->badnode = true;
q.push_back(p);
}
}
}
}
bool find_dfa()
{
node *j = tree + 1;
for (int i = 0; s[i];i++)
{
int k = s[i] - 'a';
while(j->childs[k]==NULL)
{
j = j->pre;
}
j = j->childs[k];
if(j->badnode)
{
return true;
}
}
return false;
}
int main()
{
// freopen("myin.txt", "r", stdin);
// freopen("myout.txt", "w", stdout);
int t;
cin >> t;
nums = 2;
while(t--)
{
memset(s, 0, sizeof(s));
cin >> s;
insert(tree + 1);
}
build_dfa();
cin >> t;
while(t--)
{
memset(s, 0, sizeof(s));
cin >> s;
if(find_dfa())
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}
return 0;
}