AC自动机

给定 n 个长度不超过 50 的由小写英文字母组成的单词,以及一篇长为 m 的文章。

请问,有多少个单词在文章中出现了。
#include<bits/stdc++.h>
using namespace std;
const int N=10010,S=55,M=1000010;
char str[M];
int  tr[N*S][26],q[N*S],idx;
int cnt[N*S];
int ne[N*S];
void add()
{
   
    int p=0;
    for(int i=0;str[i];i++)
    {
   
        int t=str[i]-'a';
        if(!tr[p][t])    tr[p][t] = ++idx;
        p=tr[p][t];
    }
    cnt[p]++;
}
void bfs(){
   
    int hh=0,tt=-1;
    for(int i=0;i<26;i++)
    if(tr[0][i])
    q[++tt]=tr[0][i];
    while(hh<=tt)
    {
   
        int t=q[hh++];
        for(int i=0;i<26;i++)
        {
   
            int j=ne[t];
            int c=tr[t][i];
            if(!c) continue;
            while(j && !tr[j][i]) j=ne[j];
            if(tr[j][i]) j=tr[j][i];
            ne[c]=j;
            q[++tt]=c;
        }
    }
}
int main()
{
   
    int t;
    cin>>t;
    while(t--)
    {
   
        memset(cnt,0,sizeof cnt);
        memset(ne,0,sizeof ne);
        memset(tr,0,sizeof tr);
        int n;
        cin>>n;
        for(int i=0;i<n;i++){
   
            scanf("%s",str);
            add();
        }
        bfs();
       
        scanf("%s",str);
        int res=0;
        for(int i=0,j=0;str[i];i++)
        {
   
            int c=str[i]-'a';
            while(j && !tr[j][c])   j=ne[j];
            if(tr[j][c])    j=tr[j][c];
            int p=j;
            while(p)
            {
   
                res+=cnt[p];
                cnt[p]=0;
                p=ne[p];
            }
        }
        cout<<res<<endl;
    }
    return 0;
}
全部评论

相关推荐

09-16 18:33
已编辑
西北工业大学 golang
“你也用17啊”?“对啊对啊”“我用的苹果17,你呢”“我用的小米17”
绿眼睛蓝蛙蛙:朋友们,为了「17」这个名字,我们内部其实争论了很久,很久。我自己也想了整整一年。我们一直在想:我们,到底该不该跳过「16」,直接升级到「17」? 那是一段非常煎熬的日子,有整整180个夜晚,我几乎都没怎么合眼。我和团队反复推演,一遍遍说服我们的高管团队。最终,我们决定:不妥协,不将就!顶住所有的压力,直接发布——17!
投递小米集团等公司10个岗位
点赞 评论 收藏
分享
点赞 评论 收藏
分享
想玩飞盘的菠萝蜜在春...:上交✌🏻也拒?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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