• HDU3065 病毒侵袭持续中 AC自动机


    网址:https://vjudge.net/problem/HDU-3065

    题意:

    给出$n$个模式串和一个文本串,字符集为可见字符,找出模式串在文本串中的出现次数。

    题解:

    $AC$自动机的模板题,建出$Trie$图之后跳$fail$指针匹配统计数量然后按题目要求输出即可。

    AC代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <queue>
    using namespace std;
    int cnt=0;
    int strid=0;
    struct node
    {
        string str;
        int num;
    }s[1005];
    struct AC
    {
        int trie[50005][130];
        int fail[50005];
        int cntword[50005];
        void insert(string &str)
        {
            int root=0;
            for(int i=0;i<str.size();++i)
            {
                int next=str[i];
                if(!trie[root][next])
                    trie[root][next]=++cnt;
                root=trie[root][next];
            }
            cntword[root]=++strid;
        }
        void buildfail()
        {
            queue<int>que;
            int now=0;
            for(int i=0;i<130;++i)
            {
                if(trie[now][i])
                {
                    fail[trie[now][i]]=0;
                    que.push(trie[now][i]);
                }
            }
            while(!que.empty())
            {
                now=que.front();
                que.pop();
                for(int i=0;i<130;++i)
                {
                    if(trie[now][i])
                    {
                        fail[trie[now][i]]=trie[fail[now]][i];
                        que.push(trie[now][i]);
                    }
                    else 
                        trie[now][i]=trie[fail[now]][i];
                }
            }
        }
        void query(string &str)
        {
            int next=0;
            for(int i=0;i<str.size();++i)
            {
                next=trie[next][str[i]];
                for(int j=next;j;j=fail[j])
                    ++s[cntword[j]].num;
            }
        }
    };
    AC ac;
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        int n;
        string tmp;
        while(cin>>n)
        {
            memset(ac.trie,0,sizeof(ac.trie));
            memset(ac.fail,0,sizeof(ac.fail));
            memset(ac.cntword,0,sizeof(ac.cntword));
            cnt=0,strid=0;
            for(int i=1;i<=n;++i)
            {
                cin>>tmp;
                ac.insert(tmp);
                s[i].str=tmp;
                s[i].num=0;
            }
            ac.buildfail();
            cin>>tmp;
            ac.query(tmp);
            for(int i=1;i<=n;++i)
                if(s[i].num)
                    cout<<s[i].str<<": "<<s[i].num<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    Linux cat和EOF的使用
    Linux sleep命令 和 wait命令
    Linux watch 命令
    Linux下cut命令用法
    Linux tr 命令使用
    python sqlite3使用
    SQLite数据库安装与使用
    mysql出现错误“ Every derived table must have its own alias”
    cocos2D(二)---- cocos2D文档的使用
    sqlite3 脚本的使用
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11561055.html
Copyright © 2020-2023  润新知