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;
}
全部评论

相关推荐

尊嘟假嘟点击就送:加v细说,问题很大
点赞 评论 收藏
分享
头像
11-07 01:12
重庆大学 Java
精致的小松鼠人狠话不多:签哪了哥
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务