zoukankan      html  css  js  c++  java
  • KMP与AC自动机模板

    HDU 1711 Number Sequence(KMP模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1711

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define INF 0x3f3f3f3f
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define pqueue priority_queue
    #define NEW(a,b) memset(a,b,sizeof(a))
    const double pi=4.0*atan(1.0);
    const double e=exp(1.0);
    const int maxn=1e6+8;
    typedef long long LL;
    typedef unsigned long long ULL;
    //typedef pair<LL,LL> P;
    const LL mod=1e9+7;
    using namespace std;
    int a[maxn],b[maxn],Next[maxn];
    int n,m;
    void get_next(){
        Next[0]=-1;
        int k=-1,i=0;
        while(i<m){
            while(k>-1&&b[k]!=b[i]){
                k=Next[k];
            }
            if(b[k]==b[i]||k==-1){
                k++;
            }
            Next[++i]=k;
        }
        return;
    }
    int main(){
        fio;
        int t;
        cin>>t;
        while(t--){
           cin>>n>>m;
           for(int i=0;i<n;i++){
                cin>>a[i];
           }
           for(int i=0;i<m;i++){
                cin>>b[i];
           }
           get_next();
           int p=0;
           int is=-1;
           for(int i=0;i<n;){
                if(a[i]==b[p]||p==-1){
                    p++;
                    i++;
                }
                else{
                    while(p!=-1){
                        if(b[p]==a[i]){
                            break;
                        }
                        p=Next[p];
    
                    }
                }
                if(p==m){
                    is=i-m+1;
                    break;
                }
           }
           cout<<is<<endl;
        }
    }

    HDU 2222 Keywords Search(AC自动机模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2222

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define INF 0x3f3f3f3f
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define pqueue priority_queue
    #define NEW(a,b) memset(a,b,sizeof(a))
    const double pi=4.0*atan(1.0);
    const double e=exp(1.0);
    const int maxn=1e6+8;
    typedef long long LL;
    typedef unsigned long long ULL;
    //typedef pair<LL,LL> P;
    const LL mod=1e9+7;
    using namespace std;
    struct node{
        node *nxt[26];
        node *fail;
        int is;
        void init(){
            is=0;
            fail=0;
            NEW(nxt,0);
        }
    };
    node *root;
    node *q[maxn];
    int cnt;
    void Insert(string s){
        node *p=root;
        int x;
        for(int i=0;s[i];i++){
            x=s[i]-'a';
            if(p->nxt[x]==NULL){
                p->nxt[x]=new node;
                p->nxt[x]->init();
            }
            p=p->nxt[x];
        }
        p->is++;
    }
    void build_failpoint(){
        int head=0;
        int tail=1;
        q[0]=root;
        node *tmp;
        node *f;
        while(head<tail){
            tmp=q[head++];
            for(int i=0;i<26;i++){
                if(tmp->nxt[i]){
                    if(tmp==root){
                        tmp->nxt[i]->fail=root;
                    }
                    else{
                        f=tmp->fail;
                        while(f!=0){
                            if(f->nxt[i]!=0){
                                tmp->nxt[i]->fail=f->nxt[i];
                                break;
                            }
                            f=f->fail;
                        }
                        if(f==0){
                            tmp->nxt[i]->fail=root;
                        }
                    }
                    q[tail++]=tmp->nxt[i];
                }
            }
        }
    }
    void ac_automation(string t){
        node *p=root;
        int x;
        for(int i=0;t[i];i++){
            x=t[i]-'a';
            if(p->nxt[x]){
                p=p->nxt[x];
            }
            else{
                p=p->fail;
                while(p!=0){
                    if(p->nxt[x]){
                        p=p->nxt[x];
                        break;
                    }
                    p=p->fail;
                }
                if(p==0){
                    p=root;
                }
            }
            node *tmp=p;
            while(tmp->is!=-1&&tmp!=root){
                cnt+=tmp->is;
                tmp->is=-1;
                tmp=tmp->fail;
            }
        }
    }
    int main(){
        fio;
        int t;
        int n;
        cin>>t;
        string s;
        while(t--){
           cin>>n;
           cnt=0;
           root=new node;
           root->init();
           for(int i=0;i<n;i++){
                cin>>s;
                Insert(s);
           }
           build_failpoint();
           cin>>s;
           ac_automation(s);
           cout<<cnt<<endl;
        }
    }

    AC自动机改成了数组版(表示作为下标党用不惯指针)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define INF 0x3f3f3f3f
    #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define pqueue priority_queue
    #define NEW(a,b) memset(a,b,sizeof(a))
    const double pi=4.0*atan(1.0);
    const double e=exp(1.0);
    const int maxn=1e6+8;
    typedef long long LL;
    typedef unsigned long long ULL;
    //typedef pair<LL,LL> P;
    const LL mod=1e9+7;
    using namespace std;
    struct node{
        int nxt[26];
        int fail;
        int is;
        void init(){
            is=0;
            fail=0;
            NEW(nxt,0);
        }
    }q[maxn];
    int root=1,tot=1;
    int cnt,que[maxn];
    void Insert(string s){
        int p=root;
        int x;
        for(int i=0;s[i];i++){
            x=s[i]-'a';
            if(q[p].nxt[x]==0){
                q[p].nxt[x]=++tot;
                q[q[p].nxt[x]].init();
            }
            p=q[p].nxt[x];
        }
        q[p].is++;
    }
    void build_failpoint(){
        int head=0;
        int tail=1;
        que[0]=root;
        int tmp;
        int f;
        while(head<tail){
            tmp=que[head++];
            for(int i=0;i<26;i++){
                if(q[tmp].nxt[i]){
                    if(tmp==root){
                        q[q[tmp].nxt[i]].fail=root;
                    }
                    else{
                        f=q[tmp].fail;
                        while(f!=0){
                            if(q[f].nxt[i]!=0){
                                q[q[tmp].nxt[i]].fail=q[f].nxt[i];
                                break;
                            }
                            f=q[f].fail;
                        }
                        if(f==0){
                            q[q[tmp].nxt[i]].fail=root;
                        }
                    }
                    que[tail++]=q[tmp].nxt[i];
                }
            }
        }
    }
    void ac_automation(string t){
        int p=root;
        int x;
        for(int i=0;t[i];i++){
            x=t[i]-'a';
            if(q[p].nxt[x]){
                p=q[p].nxt[x];
            }
            else{
                p=q[p].fail;
                while(p!=0){
                    if(q[p].nxt[x]){
                        p=q[p].nxt[x];
                        break;
                    }
                    p=q[p].fail;
                }
                if(p==0){
                    p=root;
                }
            }
            int tmp=p;
            while(q[tmp].is!=-1&&tmp!=root){
                cnt+=q[tmp].is;
                q[tmp].is=-1;
                tmp=q[tmp].fail;
            }
        }
    }
    int main(){
        fio;
        int t;
        int n;
        cin>>t;
        string s;
        while(t--){
           cin>>n;
           cnt=0;
           q[root].init();
           for(int i=0;i<n;i++){
                cin>>s;
                Insert(s);
           }
           build_failpoint();
           cin>>s;
           ac_automation(s);
           cout<<cnt<<endl;
        }
    }
  • 相关阅读:
    单片机多功能调试助手
    《划时代51单片机C语言全新教程》第十九章 网络通信 概览
    《划时代51单片机C语言全新教程》第十五章 按键计数器 概览
    《划时代51单片机C语言全新教程》第十七章 频率计 概览
    前后台程序框架实例2
    《划时代51单片机C语言全新教程》第二十一章 深入编程 概览
    《划时代51单片机C语言全新教程》第二十二章 界面开发 概览
    《划时代51单片机C语言全新教程》第十八章 USB通信 概览
    《划时代51单片机C语言全新教程》第二十章 深入接口 概览
    《划时代51单片机C语言全新教程》第十六章 交通灯 概览
  • 原文地址:https://www.cnblogs.com/Profish/p/9377622.html
Copyright © 2011-2022 走看看