码迷,mamicode.com
首页 > 其他好文 > 详细

AC自动机

时间:2019-09-26 21:41:23      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:ace   bit   fail   define   queue   push   std   size   string   

HDU 2222

#include <queue>
#include <iostream>
#include <string.h>
using namespace std;

#define MAX_N 1000006
#define MAX_Tot 500005

struct Aho{
    struct state{
        int next[26];
        int fail,cnt;   
    }stataTable[MAX_Tot];
    
    int size;
    queue<int> que;
    
    void init()
    {
        for(int i=0;i<MAX_Tot;i++)
        {
            memset(stataTable[i].next,0,sizeof(stataTable[i].next));
            stataTable[i].fail=stataTable[i].cnt=0;
        }
        size=1;
    }
    
    void insert(char *S)
    {
        int n=strlen(S);
        int now=0;
        for(int i=0;i<n;i++)
        {
            char c=S[i];
            if(!stataTable[now].next[c-'a'])
            {
                stataTable[now].next[c-'a']=size++;
            }
            now=stataTable[now].next[c-'a'];
         } 
         stataTable[now].cnt++;
    }
    
    void build()
    {
        stataTable[0].fail=-1;
        que.push(0);
        
        while(que.size())
        {
            int u=que.front();
            que.pop();
            for(int i=0;i<26;i++)
            {
                if(stataTable[u].next[i])
                {
                    if(u==0)
                    {
                        stataTable[stataTable[u].next[i]].fail=0;
                    }
                    else
                    {
                        int v=stataTable[u].fail;
                        while(v!=-1)
                        {
                            if(stataTable[v].next[i])
                            {
                                stataTable[stataTable[u].next[i]].fail=stataTable[v].next[i];
                                break;
                            }
                            v=stataTable[v].fail;
                        }
                        if(v==-1)
                        {
                            stataTable[stataTable[u].next[i]].fail=0;
                        }
                    }   
                    que.push(stataTable[u].next[i]);
                }
            }
        }
    }
    
    int Get(int u)
    {
        int res=0;
        while(u)
        {
            res=res+stataTable[u].cnt;
            stataTable[u].cnt=0;
            u=stataTable[u].fail;
        }
        return res;
    }
    
    int match(char *S)
    {
        int n=strlen(S);
        int res=0,now=0;
        for(int i=0;i<n;i++)
        {
            char c=S[i];
            if(stataTable[now].next[c-'a'])
            {
                now=stataTable[now].next[c-'a'];
            }
            else
            {
                int p=stataTable[now].fail;
                while(p!=-1&&stataTable[p].next[c-'a']==0)
                {
                    p=stataTable[p].fail;
                }
                if(p==-1)
                {
                    now=0;
                }
                else
                {
                    now=stataTable[p].next[c-'a'];
                }
            }
            if(stataTable[now].cnt)
            {
                res=res+Get(now);
            }
        }
        return res;
    }
}aho;

int T,N;
char S[MAX_N];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        aho.init();
        scanf("%d",&N);
        for(int i=0;i<N;i++)
        {
            scanf("%s",S);
            aho.insert(S);
         } 
         aho.build();
         scanf("%s",S);
         printf("%d\n",aho.match(S));
    }
    return 0;
}

HDU 2896

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;

struct Aho{
    struct Node{
        int next[128];
        int fail,cnt;
    }state[maxn];
    
    int size,k;
    queue<int> q;
    
    void init()
    {
        size =1 ;
        k=0;
//      for(int i=0;i<maxn;i++)
//      {
////            memset(state[i].next,0,sizeof(state[i].next));
//          state[i].cnt=state[i].fail=0;
//      }
        
    }
    
    void insert(char *S,int num)
    {
        int len=strlen(S);
        int now=0;
        for(int i=0;i<len;i++)
        {
            char c=S[i];
            if(!state[now].next[c])
            {
                state[now].next[c]=size++;
            }
            now=state[now].next[c];
        }
        state[now].cnt=num;
    }
    
    void build()
    {
        state[0].fail=-1;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<128;i++)
            {
                if(state[u].next[i])
                {
                    if(u==0)
                    {
                        state[state[u].next[i]].fail=0;
                    }
                    else
                    {
                        int v=state[u].fail;
                        while(v!=-1)
                        {
                            if(state[v].next[i])
                            {
                                state[state[u].next[i]].fail=state[v].next[i];
                                break;
                            }
                            v=state[v].fail;
                        }
                        if(v==-1)
                        {
                            state[state[u].next[i]].fail=0;
                        }
                    }
                    q.push(state[u].next[i]);
                }           
            }
        }
    }
    
    int ans[1005];
    
    void get(int now)
    {
        while(now)
        {
            if(state[now].cnt)
            {
                ans[k++]=state[now].cnt;
//              state[now].cnt=0;
            }
            now=state[now].fail;
         } 
    }
    
    int marry(char *S)
    {
        int len=strlen(S);
        int now=0;
        for(int i=0;i<len;i++)
        {
            char c=S[i];
            if(state[now].next[c])
            {
                now=state[now].next[c];
            }
            else
            {
                int p=state[now].fail;
                while(p!=-1&&state[p].next[c]==0)
                {
                    p=state[p].fail;
                }
                if(p==-1)
                {
                    now=0;
                }
                else
                {
                    now=state[p].next[c];
                }
            }
            if(state[now].cnt)
            {
                get(now);
            }
        }
        
    }
    
}aho;

int n,m;
char s[205],ss[10005];

int main()
{
    aho.init();
    int sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s);
        aho.insert(s,i);    
    }   
    aho.build();
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        aho.ans[0]=0;
        scanf("%s",ss);
        aho.marry(ss);
        sort(aho.ans,aho.ans+aho.k);
        if(aho.ans[0])
        {
            printf("web %d:",i);
            for(int j=1;j<=aho.k;j++)
            {
                if(aho.ans[j]==aho.ans[j-1])
                {
                    continue;
                }
                else
                    printf(" %d",aho.ans[j-1]);
            }
            printf("\n");
            ++sum;
        }
        aho.k=0;
    }
    printf("total: %d\n",sum);
    return 0;
 } 

HDU 3605

#include<bits/stdc++.h>
using namespace std;

const int maxn=5e4+5;
const int maxx=2e6+6;

struct Aho{
    struct Node{
        int next[26];
        int fail,cnt;
    }state[maxn];
    
    int size;
    queue<int> q;
    
    void init()
    {
        for(int i=0;i<maxn;i++)
        {
            memset(state[i].next,0,sizeof(state[i].next));
            state[i].fail=state[i].cnt=0;
        }
        size = 1;
    }
    
    void insert(char *s,int num)
    {
        int len=strlen(s);
        int now=0;
        for(int i=0;i<len;i++)
        {
            char c=s[i];
            if(!state[now].next[c-'A'])
            {
                state[now].next[c-'A']=size++;
            }
            now=state[now].next[c-'A'];
        }
        state[now].cnt=num;
    }
    
    void build()
    {
        state[0].fail=-1;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=0;i<26;i++)
            {
                if(state[u].next[i])
                {
                    if(u==0)
                    {
                        state[state[u].next[i]].fail=0;
                    }
                    else
                    {
                        int v=state[u].fail;
                        while(v!=-1)
                        {
                            if(state[v].next[i])
                            {
                                state[state[u].next[i]].fail=state[v].next[i];
                                break;
                            }
                            v=state[v].fail;
                        }
                        if(v==-1)
                        {
                            state[state[u].next[i]].fail=0;
                        }
                    }
                    q.push(state[u].next[i]);
                }
            }
        }
    }
    
    int sum[1005];
    
    void get(int now)
    {
        while(now)
        {
            if(state[now].cnt)
            {
                sum[state[now].cnt]++;
            }   
            now=state[now].fail;
        }   
    }
    
    void match(char *s)
    {
        int len=strlen(s);
        int now=0;
        for(int i=0;i<len;i++)
        {
            char c=s[i];
            if(state[now].next[c-'A'])
            {
                now=state[now].next[c-'A'];
            }
            else
            {
                int p=state[now].fail;
                while(p!=-1&&state[p].next[c-'A']==0)
                {
                    p=state[p].fail;
                }
                if(p==-1)
                {
                    now=0;
                 } 
                 else
                 {
                    now=state[p].next[c-'A'];
                 }
            }
            if(state[now].cnt)
            {
                get(now);
            }
        }
    }
}aho;

char s[1005][55];
char ss[maxx];
char sss[maxx];

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        aho.init();
        memset(aho.sum,0,sizeof(aho.sum));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s[i]);
            aho.insert(s[i],i);
        }
        aho.build();
        scanf("%s",ss);
        int len=strlen(ss);
        int k=0;
        for(int i=0;i<=len;i++)
        {
            if(ss[i]>='A'&&ss[i]<='Z')
            {
                sss[k++]=ss[i];
            }
            else
            {
                sss[k]='\0';
                aho.match(sss);
                k=0;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(aho.sum[i]) 
            {
                printf("%s: %d\n",s[i],aho.sum[i]);
            }
        }
    }
    
    return 0;
}

AC自动机

标签:ace   bit   fail   define   queue   push   std   size   string   

原文地址:https://www.cnblogs.com/tianming1/p/11594145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!