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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44489823/article/details/102767679

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

输入
第一行是整数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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44489823/article/details/102767679