• HDU 2896 (AC自动机模板题)


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2896

    题目大意:多个模式串。多个匹配串。其中串的字符范围是(0~127)。问匹配串中含有哪几个模式串。

    解题思路

    AC自动机模板题。注意一下字符范围。

    cnt记录这个模式串的个数改为这个模式串的index。

    find的时候,把找到的index压入vector里面即可。

    注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,再还原回来。

    #include "cstdio"
    #include "cstring"
    #include "string"
    #include "iostream"
    #include "queue"
    #include "vector"
    #include "algorithm"
    using namespace std;
    #define maxn 130
    struct Trie
    {
        Trie *next[maxn],*fail;
        int cnt;
    }*root;
    struct status
    {
        Trie *last;
        int cnt;
        status(Trie *last,int cnt):last(last),cnt(cnt) {}
    };
    Trie *newnode()
    {
        Trie *ret=new Trie;
        memset(ret->next,0,sizeof(ret->next));
        ret->fail=0;
        ret->cnt=0;
        return ret;
    }
    void init() {root=newnode();}
    void Insert(string str,int index)
    {
        Trie *pos=root;
        for(int i=0;i<str.size();i++)
        {
            int c=str[i];
            if(!pos->next[c]) pos->next[c]=newnode();
            pos=pos->next[c];
        }
        pos->cnt=index;
    }
    void getfail()
    {
        queue<Trie *> Q;
        for(int c=0;c<maxn;c++)
        {
            if(root->next[c])
            {
                root->next[c]->fail=root;
                Q.push(root->next[c]);
            }
            else root->next[c]=root;
        }
        while(!Q.empty())
        {
            Trie *x=Q.front();Q.pop();
            for(int c=0;c<maxn;c++)
            {
                if(x->next[c])
                {
                    x->next[c]->fail=x->fail->next[c];
                    Q.push(x->next[c]);
                }
                else x->next[c]=x->fail->next[c];
            }
        }
    }
    vector<int> find(string str)
    {
        Trie *pos=root,*last;
        queue<status> Q;
        vector<int> ans;
        for(int i=0;i<str.size();i++)
        {
            int c=str[i];last;
            if(pos->next[c])
            {
                pos=pos->next[c];
                last=pos;
                while(last->cnt)
                {
                    Q.push(status(last,last->cnt));
                    ans.push_back(last->cnt);
                    last->cnt=0; //修改last->cnt
                    last=last->fail;
                }
            }
        }
        while(!Q.empty()) //恢复last->cnt
        {
            status x=Q.front();Q.pop();
            x.last->cnt=x.cnt;
        }
        return ans;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        ios::sync_with_stdio(false);
        int n,m;
        string tt;
        while(cin>>n)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                cin>>tt;
                Insert(tt,i);
            }
            getfail();
            cin>>m;
            int cnt=0;
            for(int i=1;i<=m;i++)
            {
                cin>>tt;
                vector<int> ans=find(tt);
                sort(ans.begin(),ans.end());
                if(!ans.size()) continue;
                cnt++;
                printf("web %d:",i);
                for(int j=0;j<ans.size();j++) printf(" %d",ans[j]);
                printf("
    ");
            }
            printf("total: %d
    ",cnt);
        }
    }
  • 相关阅读:
    markdown语法及工具
    关于div的宽度或高度设置为100%时
    响应式css垂直居中
    JavaScript之闭包问题以及立即执行函数
    JavaScript和JQuery好书推荐
    数组中去重
    解决getImageData跨域问题
    js在for循环中绑定事件
    表格横竖颠倒
    上传按钮美化遇到的问题
  • 原文地址:https://www.cnblogs.com/neopenx/p/4040486.html
Copyright © 2020-2023  润新知