zoukankan      html  css  js  c++  java
  • AC自动机

    手写了下AC自动机,真正理解了kmp之后手写AC自动机还是很简单的。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    struct Trie
    {
        int ch[maxn][26];
        int End[maxn];
        int f[maxn];
        int last[maxn];
        int rt,L;
        int newnode()
        {
            ++L;
            memset(ch[L],-1,sizeof(ch[L]));
            End[L]=0;
            return L;
        }
        void init()
        {
            L=-1;
            rt=newnode();
        }
        void insert(char *s)
        {
            int len=strlen(s);
            int u=rt;
            REP(i,0,len-1){
                int c=s[i]-'a';
                if(ch[u][c]==-1) ch[u][c]=newnode();
                u=ch[u][c];
            }
            End[u]++;
        }
        int get(int u)
        {
            if(!u) return 0;
            int res=End[u]+get(last[u]);
            End[u]=0;
            return res;
        }
        int find(char *s)
        {
            int res=0;
            int len=strlen(s);
            int u=rt;
            REP(i,0,len-1){
                int c=s[i]-'a';
                u=ch[u][c];
                if(End[u]) res+=get(u);
                else if(last[u]) res+=get(last[u]);
            }
            return res;
        }
        void build()
        {
            queue<int> q;
            REP(c,0,25){
                if(~ch[rt][c]) q.push(ch[rt][c]),f[ch[rt][c]]=rt;
                else ch[rt][c]=rt;
            }
            while(!q.empty()){
                int u=q.front();q.pop();
                last[u]=rt;
                REP(c,0,25){
                    if(~ch[u][c]) f[ch[u][c]]=ch[f[u]][c],q.push(ch[u][c]);
                    else ch[u][c]=ch[f[u]][c];
                    if(End[f[u]]) last[u]=f[u];
                    else last[u]=last[f[u]];
                }
            }
        }
    };Trie ac;
    int n;
    char s[maxn],t[maxn];
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
        #endif // ONLINE_JUDGE
        int T;cin>>T;
        while(T--){
            scanf("%d",&n);
            ac.init();
            REP(i,1,n){
                scanf("%s",t);
                ac.insert(t);
            }
            ac.build();
            scanf("%s",s);
            printf("%d
    ",ac.find(s));
        }
        return 0;
    }
    View Code

     我觉得还是把上面找last的语句写到循环的外面比较好,虽然没什么区别,但写到外面才是准确的,谁叫我有代码强迫症。。。还是懒得改了,下次就写到外面吧。。。

    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    MySQl数据约束练习
    MySQL查询实例
    网络通信协议简介(TCP与UDP)
    数据类型转换
    C++编译过的C代码为什么要用extern C
    hashtable
    以RB-tree为底层机制的几个关联式容器
    红黑树(RB-Tree)
    slist
    deque
  • 原文地址:https://www.cnblogs.com/--560/p/5259927.html
Copyright © 2011-2022 走看看