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;
        }
    }
  • 相关阅读:
    Window 窗口类
    使用 Bolt 实现 GridView 表格控件
    lua的table库
    Windows编程总结之 DLL
    lua 打印 table 拷贝table
    使用 xlue 实现简单 listbox 控件
    使用 xlue 实现 tips
    extern “C”
    COleVariant如何转换为int double string cstring
    原来WIN32 API也有GetOpenFileName函数
  • 原文地址:https://www.cnblogs.com/Profish/p/9377622.html
Copyright © 2011-2022 走看看