ac自动机模板

%yyb

通俗易懂的ac自动机教程 : https://www.cnblogs.com/cjyyb/p/7196308.html

板子题四道:

开一篇博客存一下板子(第一题ac代码)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 3;
struct Trie {
    int fail,ch[27],cnt;
}ac[maxn];
int tot=0;
void Insert(char s[])
{
    int len=strlen(s),now=0;
    for(int i=0;i<len;i++) {
        if(!ac[now].ch[s[i]-'a']) ac[now].ch[s[i]-'a']=++tot;
        now=ac[now].ch[s[i]-'a'];
    }
    ac[now].cnt++;
}
void build()
{
    ac[0].fail=0;
    queue<int> q;
    for(int i=0;i<26;i++) if(ac[0].ch[i])   
    {
        ac[ac[0].ch[i]].fail=0; q.push(ac[0].ch[i]);
    }
    while(!q.empty())
    {
        int now=q.front(); q.pop();
        for(int i=0;i<26;i++)
            if(ac[now].ch[i])
            {
                ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i];
                q.push(ac[now].ch[i]);
            }
            else ac[now].ch[i]=ac[ac[now].fail].ch[i];
    }
}
int query(char s[])
{
    int len=strlen(s),ans=0,now=0,tmp;
    for(int i=0;i<len;i++) {
        now=ac[now].ch[s[i]-'a'];
        tmp=now;
        while(tmp&&ac[tmp].cnt)
        {
            ans+=ac[tmp].cnt;
            ac[tmp].cnt=0;
            tmp=ac[tmp].fail;
        }
    }
    return ans;
}
int main()
{
    int n;
    char s[maxn];
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%s",s);
        Insert(s);
    }
    build();
    scanf("%s",s);
    printf("%d",query(s));
    return 0;
}

第四题代码(第一题改为多组数据需要每次初始化,初始化50*n的大小即可)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 3;
struct Trie {
    int fail,ch[27],cnt;
}ac[maxn];
int tot=0;
void Insert(char s[])
{
    int len=strlen(s),now=0;
    for(int i=0;i<len;i++) {
        if(!ac[now].ch[s[i]-'a']) ac[now].ch[s[i]-'a']=++tot;
        now=ac[now].ch[s[i]-'a'];
    }
    ac[now].cnt++;
}
void build()
{
    ac[0].fail=0;
    queue<int> q;
    for(int i=0;i<26;i++) if(ac[0].ch[i])    
    {
        ac[ac[0].ch[i]].fail=0; q.push(ac[0].ch[i]);
    }
    while(!q.empty())
    {
        int now=q.front(); q.pop();
        for(int i=0;i<26;i++)
            if(ac[now].ch[i])
            {
                ac[ac[now].ch[i]].fail=ac[ac[now].fail].ch[i];
                q.push(ac[now].ch[i]);
            }
            else ac[now].ch[i]=ac[ac[now].fail].ch[i];
    }
}
int query(char s[])
{
    int len=strlen(s),ans=0,now=0,tmp;
    for(int i=0;i<len;i++) {
        now=ac[now].ch[s[i]-'a'];
        tmp=now;
        while(tmp&&ac[tmp].cnt)
        {
            ans+=ac[tmp].cnt;
            ac[tmp].cnt=0;
            tmp=ac[tmp].fail;
        }
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        char s[maxn];
        scanf("%d",&n);
        for(int i=0;i<=n*50;i++) {
            ac[i].cnt=0;
            for(int j=0;j<26;j++) ac[i].ch[j]=0;
        }
        for(int i=1;i<=n;i++) {
            scanf("%s",s);    
            Insert(s);
        }
        build();    
        scanf("%s",s);
        printf("%d\n",query(s));
    }
    return 0;
}






全部评论

相关推荐

10-24 00:54
已编辑
门头沟学院 Java
牛客20646354...:这连小厂都找不到就离谱,只能说可能你根本没投什么小厂。说实话现在都要11月了,没什么岗位了。其实最好是在9月找,那时候暑假工刚走,岗位多的是,现在都占满了岗位了,秋招的秋招,顶替暑假工的也基本上都顶替了。 只能多投了,简历其实都差不多,你这都不是外卖+点评去找实习了,已经比好多人优秀了。实在找不到,可以降低一些标准的,能投到自研项目的小厂说实话可能比你去中大厂能学到更多东西。因为中大厂最多给你看一点点模块功能,小厂基本上全部代码甚至几个项目的代码都能拿到。
点赞 评论 收藏
分享
牛至超人:把哈工大,再加大加粗,看见闪闪发光的哈工大字样,面试官直接流口水
投递字节跳动等公司7个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务