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

描述
給若干個模式串,以及若干個句子,判斷每個句子裏是否包含模式串。 句子和模式串都由小寫字母組成

輸入
第一行是整數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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章