模板 AC自动机

板子题目:

n个串以及1个总串,求出n个串内在这个总串内(整串)出现的个数。

即HDU2222


AC自动机的模板题目。

AC自动机主要就是fail指针的巧妙性。。

什么是AC自动机我就不说了,网上资料也是很多的……

在这里就给出我一直在用的代码吧。

首先当然是把那n个串放入trie树了……然后匹配。。

中间AC()也就是求fail的过程值得记一记。


感觉这份代码还是挺好的。


#include<bits/stdc++.h>
using namespace std;
int n,sz,len;
int trie[1000005][26],val[1000005],fail[1000005],flag[1000005];
char ty1[55],ty2[1000005];
int Q[50005];
int find(int x,int t){
    if (trie[x][t]) return trie[x][t];
    if (!x) return 0;
    return find(fail[x],t);
}        //类似于KMP的find函数
void insert(){
    int now=0;
    int len=strlen(ty1);
    for (int i=0;i<len;i++){
        int t=ty1[i]-'a';
        if (trie[now][t]) now=trie[now][t];
            else now=trie[now][t]=++sz;
    }
    val[now]++;        //在now上的单词个数val[now]
}
void AC(){     //广搜求出fail指针
    int head=0,tail=1;
    Q[0]=0;
    while (head<tail){
        int now=Q[head++];
        for (int i=0;i<26;i++){
            if (!trie[now][i]) continue;
            int t=find(fail[now],i);
            if (!now) t=0;
            fail[trie[now][i]]=t;
            Q[tail++]=trie[now][i];
        }
    }
}
void solve(){
    int t=0,ans=0;
    for (int i=0;i<len;i++){
        int tt=ty2[i]-'a';
        flag[t]=1;
        t=find(t,tt);
        if (flag[t]) continue;
        for (int j=t;j;j=fail[j])
            ans+=val[j],val[j]=0;
    }
    printf("%d\n",ans);
}
int main(){
    int fil;
    scanf("%d",&fil);    //多组数据
    while (fil--){
        memset(val,0,sizeof(val));
        memset(trie,0,sizeof(trie));
        memset(fail,0,sizeof(fail));
        memset(flag,0,sizeof(flag));
        scanf("%d",&n);
        sz=0;
        for (int i=1;i<=n;i++){
            scanf("%s",ty1);
            insert();        //放入trie树
        }
        AC();
        scanf("%s",ty2);
        len=strlen(ty2);
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值