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

AC自动机

时间:2019-07-31 11:26:17      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:nbsp   pre   get   自动   name   break   std   mamicode   技术   

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

const int maxn=2000101;
struct node
{
    int son[30],flag,fail,ans;
    void clear()
    {
        memset(son,0,sizeof(son));
        fail=flag=0;
    }
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn],T[maxn];
queue<int>q;
struct ac
{
    struct node
    {
        int son[30],flag,fail,ans;
        void clear()
        {
            memset(son,0,sizeof(son));
            fail=flag=0;
        }
    } trie[maxn];

    int in[maxn],ans;
    void init()
    {
        for (int i=0; i<=cnt; i++)
        {
            trie[i].clear();
        }
        for (int i=1; i<=n; i++)
        {
            vis[i]=0;
        }
        cnt=1;
        ans=0;
    }

    void insert_(char *str,int num)
    {
        int u=1,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            if (!trie[u].son[id])
            {
                trie[u].son[id]=++cnt;
            }
            u=trie[u].son[id];
        }
        if (!trie[u].flag) trie[u].flag=num;
        Map[num]=trie[u].flag;
    }

    void getfail()
    {
        for (int i=0; i<26; i++)
        {
            trie[0].son[i]=1;
        }
        q.push(1);
        while (!q.empty())
        {

            int u=q.front();
            q.pop();
            int fail=trie[u].fail;
            for (int i=0; i<26; i++)
            {
                int v=trie[u].son[i];
                if (!v)
                {
                    trie[u].son[i]=trie[fail].son[i];
                    continue;
                }
                trie[v].fail=trie[fail].son[i];
                in[trie[v].fail]++;
                q.push(v);
            }
        }
    };

    void topu()
    {
        for (int i=1; i<=cnt; i++)
        {
            if (!in[i])
            {
                q.push(i);
            }
        }
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[trie[u].flag]=trie[u].ans;
            int v=trie[u].fail;
            trie[v].ans+=trie[u].ans;
            if (!--in[v])
            {
                q.push(v);
            }
        }
    }

    void query(char *str)
    {
        int u=1,ans=0,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            u=trie[u].son[id];
            trie[u].ans++;
        }
    }
} AC;

int main()
{
    scanf("%d",&n);
    AC.init();
    for (int i=1; i<=n; i++)
    {
        scanf("%s",s);
        AC.insert_(s,i);
    }
    AC.getfail();
    scanf("%s",T);

    AC.query(T);
    AC.topu();
    for (int i=1; i<=n; i++)
    {
        printf("%d\n",vis[Map[i]]);
    }
}

技术图片

 

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

const int maxn=2000101;
struct node
{
    int son[30],flag,fail,ans;
    void clear()
    {
        memset(son,0,sizeof(son));
        fail=flag=0;
    }
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn][80],T[maxn];
queue<int>q;
struct ac
{
    struct node
    {
        int son[30],flag,fail,ans;
        void clear()
        {
            memset(son,0,sizeof(son));
            fail=flag=ans=0;
        }
    } trie[maxn];
    int in[maxn],ans;
    void init()
    {
        for (int i=0; i<=cnt; i++)
        {
            trie[i].clear();
        }
        for (int i=1; i<=n; i++)
        {
            vis[i]=0;
        }
        cnt=1;
    }

    void insert_(char *str,int num)
    {
        int u=1,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            if (!trie[u].son[id])
            {
                trie[u].son[id]=++cnt;
            }
            u=trie[u].son[id];
        }
        if (!trie[u].flag) trie[u].flag=num;
        Map[num]=trie[u].flag;
    }

    void getfail()
    {
        for (int i=0; i<26; i++)
        {
            trie[0].son[i]=1;
        }
        q.push(1);
        while (!q.empty())
        {

            int u=q.front();
            q.pop();
            int fail=trie[u].fail;
            for (int i=0; i<26; i++)
            {
                int v=trie[u].son[i];
                if (!v)
                {
                    trie[u].son[i]=trie[fail].son[i];
                    continue;
                }
                trie[v].fail=trie[fail].son[i];
                in[trie[v].fail]++;
                q.push(v);
            }
        }
    };

    void topu()
    {
        for (int i=1; i<=cnt; i++)
        {
            if (!in[i])
            {
                q.push(i);
            }
        }
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[trie[u].flag]=trie[u].ans;
            int v=trie[u].fail;
            trie[v].ans+=trie[u].ans;
            if (!--in[v])
            {
                q.push(v);
            }
        }
    }

    void query(char *str)
    {
        int u=1,ans=0,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            u=trie[u].son[id];
            trie[u].ans++;
        }
    }
} AC;

int main()
{
    while (1)
    {
        memset(vis,0,sizeof(vis));
        memset(Map,0,sizeof(Map));
        scanf("%d",&n);
        if (n==0){
            break;
        }
        AC.init();
        for (int i=1; i<=n; i++)
        {
            scanf("%s",s[i]);
            AC.insert_(s[i],i);
        }
        AC.getfail();
        scanf("%s",T);
        AC.query(T);
        AC.topu();
        int mx=0;
        for (int i=1; i<=n; i++)
        {
            mx=max(mx,vis[Map[i]]);
        }
        printf("%d\n",mx);
        for (int i=1;i<=n;i++){
            if (vis[Map[i]]==mx){
                printf("%s\n",s[Map[i]]);
            }
        }
    }
}

 技术图片

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

const int maxn=2000101;
struct node
{
    int son[30],flag,fail,ans;
    void clear()
    {
        memset(son,0,sizeof(son));
        fail=flag=0;
    }
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn],T[maxn];
queue<int>q;
struct ac
{
    struct node
    {
        int son[30],flag,fail,ans;
        void clear()
        {
            memset(son,0,sizeof(son));
            fail=flag=0;
        }
    } trie[maxn];

    int in[maxn],ans;
    void init()
    {
        for (int i=0; i<=cnt; i++)
        {
            trie[i].clear();
        }
        for (int i=1; i<=n; i++)
        {
            vis[i]=0;
        }
        cnt=1;
        ans=0;
    }

    void insert_(char *str,int num)
    {
        int u=1,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            if (!trie[u].son[id])
            {
                trie[u].son[id]=++cnt;
            }
            u=trie[u].son[id];
        }
        if (!trie[u].flag) trie[u].flag=num;
        Map[num]=trie[u].flag;
    }

    void getfail()
    {
        for (int i=0; i<26; i++)
        {
            trie[0].son[i]=1;
        }
        q.push(1);
        while (!q.empty())
        {

            int u=q.front();
            q.pop();
            int fail=trie[u].fail;
            for (int i=0; i<26; i++)
            {
                int v=trie[u].son[i];
                if (!v)
                {
                    trie[u].son[i]=trie[fail].son[i];
                    continue;
                }
                trie[v].fail=trie[fail].son[i];
                in[trie[v].fail]++;
                q.push(v);
            }
        }
    };

    void topu()
    {
        for (int i=1; i<=cnt; i++)
        {
            if (!in[i])
            {
                q.push(i);
            }
        }
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[trie[u].flag]=trie[u].ans;
            int v=trie[u].fail;
            trie[v].ans+=trie[u].ans;
            if (!--in[v])
            {
                q.push(v);
            }
        }
    }

    void query(char *str)
    {
        int u=1,ans=0,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            u=trie[u].son[id];
            trie[u].ans++;
        }
    }
} AC;

int main()
{
    scanf("%d",&n);
    AC.init();
    for (int i=1; i<=n; i++)
    {
        scanf("%s",s);
        AC.insert_(s,i);
    }
    AC.getfail();
    scanf("%s",T);

    AC.query(T);
    AC.topu();
    for (int i=1; i<=n; i++)
    {
        printf("%d\n",vis[Map[i]]);
    }
}

 技术图片

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

const int maxn=2000101;
struct node
{
    int son[30],flag,fail,ans;
    void clear()
    {
        memset(son,0,sizeof(son));
        fail=flag=0;
    }
} trie[maxn];
int n,cnt,vis[maxn],Map[maxn];
char s[maxn][80],T[maxn];
queue<int>q;
struct ac
{
    struct node
    {
        int son[30],flag,fail,ans;
        void clear()
        {
            memset(son,0,sizeof(son));
            fail=flag=ans=0;
        }
    } trie[maxn];
    int in[maxn],ans;
    void init()
    {
        for (int i=0; i<=cnt; i++)
        {
            trie[i].clear();
        }
        for (int i=1; i<=n; i++)
        {
            vis[i]=0;
        }
        cnt=1;
    }

    void insert_(char *str,int num)
    {
        int u=1,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            if (!trie[u].son[id])
            {
                trie[u].son[id]=++cnt;
            }
            u=trie[u].son[id];
        }
        if (!trie[u].flag) trie[u].flag=num;
        Map[num]=trie[u].flag;
    }

    void getfail()
    {
        for (int i=0; i<26; i++)
        {
            trie[0].son[i]=1;
        }
        q.push(1);
        while (!q.empty())
        {

            int u=q.front();
            q.pop();
            int fail=trie[u].fail;
            for (int i=0; i<26; i++)
            {
                int v=trie[u].son[i];
                if (!v)
                {
                    trie[u].son[i]=trie[fail].son[i];
                    continue;
                }
                trie[v].fail=trie[fail].son[i];
                in[trie[v].fail]++;
                q.push(v);
            }
        }
    };

    void topu()
    {
        for (int i=1; i<=cnt; i++)
        {
            if (!in[i])
            {
                q.push(i);
            }
        }
        while (!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[trie[u].flag]=trie[u].ans;
            int v=trie[u].fail;
            trie[v].ans+=trie[u].ans;
            if (!--in[v])
            {
                q.push(v);
            }
        }
    }

    void query(char *str)
    {
        int u=1,ans=0,len=strlen(str);
        for (int i=0; i<len; i++)
        {
            int id=str[i]-‘a‘;
            u=trie[u].son[id];
            trie[u].ans++;
        }
    }
} AC;

int main()
{
        int ans=0;
        scanf("%d",&n);
        AC.init();
        for (int i=1; i<=n; i++)
        {
            scanf("%s",s[i]);
            AC.insert_(s[i],i);
        }
        AC.getfail();
        scanf("%s",T);
        AC.query(T);
        AC.topu();
        int mx=0;
        for (int i=1; i<=n; i++)
        {
            if (vis[Map[i]])
            {
                ans++;
            }
        }
        printf("%d\n",ans);
}

 

AC自动机

标签:nbsp   pre   get   自动   name   break   std   mamicode   技术   

原文地址:https://www.cnblogs.com/Accpted/p/11274455.html

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