zoukankan      html  css  js  c++  java
  • AC自动机-题目集合

     AC自动机-题目集合 模板

      如果你想要学习AC自动机,推荐一些学习资料.

    学习可以看这篇博客 http://blog.csdn.net/niushuai666/article/details/7002823

    或者看看大佬的视频讲解 http://www.bilibili.com/video/av6295004/

    下面是一些AC自动机的一些入门题目.和AC代码,先学再做练习.


    题目链接: hdu-2222

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<stdlib.h>
    #include<time.h>
    
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1e9+7;
    const int MAXSIZE=1e6+5;
    const double eps=0.0000000001;
    void fre()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    #define memst(a,b) memset(a,b,sizeof(a))
    #define fr(i,a,n) for(int i=a;i<n;i++)
    
    const int MAXNode=5e5+5;
    struct Aho
    {
        int ch[MAXNode][26]; // 多模式字符串 需要构建的 Tire(字典树)
        int last[MAXNode];   //  统计某一个模式串 (在Tire中MaxNode位置结尾的字符串) 个数,
        int fail[MAXNode]; //失配指针
        int sz,root;
        int newnode()
        {
            memset(ch[sz],-1,sizeof(ch[sz]));
            last[sz++]=0;
            return sz-1;
        }
        void init()
        {
            sz=0;
            root=newnode();
        }
        void insert(char *s)
        {
            int len=strlen(s);
            int now=root;
            for(int i=0; i<len; i++)
            {
                if(ch[now][s[i]-'a']==-1) ch[now][s[i]-'a']=newnode();
                now=ch[now][s[i]-'a'];
            }
            last[now]++;
        }
        void GetFail()// 如何构建失败指针,还是不太会.所以套 kuangbin 模板
        {
            queue<int>Q;
            fail[root]=root;
            for(int i = 0; i < 26; i++)
            {
                if(ch[root][i]==-1)
                    ch[root][i]=root;
                else
                {
                    fail[ch[root][i]]=root;
                    Q.push(ch[root][i]);
                }
            }
            while(!Q.empty())
            {
                int now=Q.front();
                Q.pop();
                for(int i=0; i<26; i++)
                {
                    if(ch[now][i]==-1)
                        ch[now][i]=ch[fail[now]][i];
                    else
                    {
                        fail[ch[now][i]]=ch[fail[now]][i];
                        Q.push(ch[now][i]);
                    }
                }
            }
        }
        int match(char *s)
        {
            int len=strlen(s);
            int now=root;
            int res=0;
            for(int i=0; i<len; i++)
            {
                now=ch[now][s[i]-'a'];
                int temp=now;
                while(temp!=root)
                {
                    res+=last[temp];
                    last[temp]=0;
                    temp=fail[temp];
                }
            }
            return res;
        }
    } ac;
    char str[MAXSIZE];
    inline void read(int& ret) //适用于正整数
    {
        char c;
        ret=0;
        while((c=getchar())<'0'||c>'9');
        while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
    }
    int main(int argc,char *argv[])
    {
        int ncase;
        read(ncase);
        while(ncase--)
        {
            int n;
            ac.init();
            scanf("%d",&n);
            for(int i=0; i<n; i++)
            {
                scanf("%s",str);
                ac.insert(str);
            }
            ac.GetFail();
            scanf("%s",str);
            printf("%d
    ",ac.match(str));
        }
        return 0;
    }
    
    /**  http://blog.csdn.net/wr_technology  */
    


    鄙人只是存模板,失配指针怎么构建,目前正在学习之中。若想要学习 AC自动机。请点这篇博文。总结的详细。


    ------------------------------------------  分割线  ---------------------------------------------------------


    上面是kuangbin模板,不太会。因为他在构建fail指针的的时候不是最简单的方法。所以我又找了一另一个代码来学习,这一份就是朴素的方法,不像kuangbin模板优化过,不适合初学者。


    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<stdlib.h>
    #include<time.h>
    
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1e9+7;
    const int MAXSIZE=1e6+5;
    const double eps=0.0000000001;
    void fre()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    #define memst(a,b) memset(a,b,sizeof(a))
    #define fr(i,a,n) for(int i=a;i<n;i++)
    
    const int MAXNode=5e5+5;
    struct Aho
    {
        int ch[MAXNode][26]; // 多模式字符串 需要构建的 Tire(字典树)
        int last[MAXNode];   //  统计某一个模式串 (在Tire中MaxNode位置结尾的字符串) 个数,
        int fail[MAXNode]; //失配指针
        int sz,root;
        int newnode()
        {
            memset(ch[sz],-1,sizeof(ch[sz]));
            last[sz++]=0;
            return sz-1;
        }
        void init()
        {
            sz=0;
            root=newnode();
        }
        void insert(char *s)
        {
            int len=strlen(s);
            int now=root;
            for(int i=0; i<len; i++)
            {
                if(ch[now][s[i]-'a']==-1) ch[now][s[i]-'a']=newnode();
                now=ch[now][s[i]-'a'];
            }
            last[now]++;
        }
        void GetFail()//
        {
            queue<int>Q;
            Q.push(root);
            while(!Q.empty())
            {
                int now=Q.front();
                Q.pop();
                for(int i=0;i<26;i++)
                {
                    if(ch[now][i]!=-1)
                    {
                        if(now==root) fail[ch[now][i]]=root;
                        else
                        {
                            int temp=fail[now];
                            while(temp&&ch[temp][i]==-1) temp=fail[temp];
                            fail[ch[now][i]]=ch[temp][i];
                        }
                        Q.push(ch[now][i]);
                    }
                }
            }
            return ;
        }
        int match(char *s)
        {
            int len=strlen(s);
            int now=root,temp;
            int res=0;
            for(int i=0; i<len; i++)
            {
    
                while(now&&ch[now][s[i]-'a']==-1) 
                    now=fail[now];temp=now=ch[now][s[i]-'a'];
                while(temp!=root)
                {
                    res+=last[temp];
                    last[temp]=0;
                    temp=fail[temp];
                }
            }
            return res;
        }
    } ac;
    char str[MAXSIZE];
    inline void read(int& ret)
    {
        char c;
        ret=0;
        while((c=getchar())<'0'||c>'9');
        while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
    }
    int main(int argc,char *argv[])
    {
        int ncase;
        read(ncase);
        while(ncase--)
        {
            int n;
            ac.init();
            scanf("%d",&n);
            for(int i=0; i<n; i++)
            {
                scanf("%s",str);
                ac.insert(str);
            }
            ac.GetFail();
            scanf("%s",str);
            printf("%d
    ",ac.match(str));
        }
        return 0;
    }
    
    /**  http://blog.csdn.net/wr_technology  */
    

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面是 hdu-2896 

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<stdlib.h>
    #include<time.h>
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1e9+7;
    const int MAXSIZE=1e6+5;
    const double eps=0.0000000001;
    void fre()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    #define memst(a,b) memset(a,b,sizeof(a))
    #define fr(i,a,n) for(int i=a;i<n;i++)
    const int MAXNode=5e5+5;
    
    
    int ans[10005][505],cnt[505];
    struct Aho
    {
        int ch[100000][128]; // 多模式字符串 需要构建的 Tire(字典树)
        int last[MAXNode];   //  统计某一个模式串 (在Tire中MaxNode位置结尾的字符串) 个数,
        int fail[MAXNode]; //失配指针
        int sz,root;
        int newnode()
        {
            memset(ch[sz],-1,sizeof(ch[sz]));
            last[sz++]=0;
            return sz-1;
        }
        void init()
        {
            sz=0;
            root=newnode();
        }
        void insert(char *s,int id)
        {
            int now=root;
            for(int i=0;  s[i]!='' ; i++)
            {
                if(ch[now][(int)s[i]]==-1) ch[now][(int)s[i]]=newnode();
                now=ch[now][(int)s[i]];
            }
            last[now]=id;
        }
        void GetFail()
        {
            queue<int>Q;
            Q.push(root);
            while(!Q.empty())
            {
                int now=Q.front();
                Q.pop();
                for(int i=0; i<128; i++)
                {
                    if(ch[now][i]!=-1)
                    {
                        if(now==root) fail[ch[now][i]]=root;
                        else
                        {
                            int temp=fail[now];
                            while(temp&&ch[temp][i]==-1) temp=fail[temp];
                            fail[ch[now][i]]=ch[temp][i];
                        }
                        Q.push(ch[now][i]);
                    }
                }
            }
            return ;
        }
        void match(char *s,int id)
        {
            int  flag[550];
            memset(flag,0,sizeof(flag));
            int now=root,temp;
            for(int i=0; s[i]!=''; i++)
            {
    
                while(now&&ch[now][(int)s[i]]==-1)
                    now=fail[now];
                temp=now=ch[now][(int)s[i]];
                while(temp!=root&&flag[last[temp]]==0)
                {
                    if(last[temp])
                    {
                        ans[id][cnt[id]++]=last[temp];
                        flag[last[temp]]=1;
                    }
                    temp=fail[temp];
                }
                if(cnt[id]>=3) break;
            }
            return ;
        }
    } ac;
    char str[MAXSIZE];
    void print(int m)
    {
        int sum=0;
        for(int i=1; i<=m; i++)
        {
            if(!cnt[i]) continue;
            printf("web %d:",i);
            for(int j=0; j<cnt[i]; j++) printf(" %d",ans[i][j]);
            printf("
    ");
            sum++;
        }
        printf("total: %d
    ",sum);
    }
    
    int main(int argc,char *argv[])
    {
        int n,m;
        scanf("%d",&n);
        getchar();
        memset(cnt,0,sizeof(cnt));
        ac.init();
        for(int i=1; i<=n; i++)
        {
            gets(str);
            ac.insert(str,i);
        }
        ac.GetFail();
        scanf("%d",&m);
        getchar();
        for(int j=1; j<=m; j++)
        {
            scanf("%s",str);
            ac.match(str,j);
            sort(ans[j],ans[j]+cnt[j]);
        }
        print(m);
        return 0;
    }

    -----------------------------------------------------------------------------------------------------------------------


    hihocoder-1036

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<stdlib.h>
    #include<time.h>
    
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1e9+7;
    const int MAXSIZE=1e6+5;
    const double eps=0.0000000001;
    void fre()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    #define memst(a,b) memset(a,b,sizeof(a))
    #define fr(i,a,n) for(int i=a;i<n;i++)
    
    const int MAXNode=5e6+5;
    
    struct Aho
    {
        int ch[MAXNode][26],fail[MAXNode],last[MAXNode],root,sz;
        int newnode()
        {
            memset(ch[sz],-1,sizeof(ch[sz]));
            last[sz++]=0;
            return sz-1;
        }
        void init()
        {
            sz=0;
            root=newnode();
        }
        void insert(char *s)
        {
            int now=root;
            for(int i=0; s[i]!=''; i++)
            {
                int id=(int)(s[i]-'a');
                if(ch[now][id]==-1) ch[now][id]=newnode();
                now=ch[now][id];
            }
            last[now]=1;
        }
        void GetFail()
        {
            queue<int>Q;
            fail[root]=root;
            Q.push(root);
            while(!Q.empty())
            {
                int now=Q.front();
                Q.pop();
                for(int i=0; i<26; i++)
                {
                    if(now==root)
                    {
                        if(ch[now][i]==-1) ch[now][i]=root;
                        else fail[ch[now][i]]=root,Q.push(ch[now][i]);
                    }
                    else
                    {
                        if(ch[now][i]==-1) ch[now][i]=ch[fail[now]][i];
                        else fail[ch[now][i]]=ch[fail[now]][i],Q.push(ch[now][i]);
                    }
                }
            }
        }
        bool match(char *s)
        {
            int now=root;
            for(int i=0; s[i]!=''; i++)
            {
                now=ch[now][(int)(s[i]-'a')];
                if(last[now]) return true;
            }
            return false;
        }
    } ac;
    char str[MAXSIZE];
    int main()
    {
        int n;
        cin>>n;
        ac.init();
        for(int i=0; i<n; i++)
        {
            scanf("%s",str);
            ac.insert(str);
        }
        scanf("%s",str);
        ac.GetFail();
        if(ac.match(str)) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        return 0;
    }
    





  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207945.html
Copyright © 2011-2022 走看看