Processing math: 100%

[模板][P3808]AC自动机(简单版)

Description:

求n个模式串中有几个在文本串中出现

Solution:

模板,详见代码:

#include<bits/stdc++.h>
using namespace std;
const int mxn=1e7+5;
char str[mxn],p[80];
queue<int > q;

namespace Trie {
    int tot,fail[mxn],val[mxn];
    int t[mxn][26];
    void ins(char *s) {
        int len=strlen(s),u=0;
        for(int i=0;i<len;++i) {
            if(!t[u][s[i]-'a']) t[u][s[i]-'a']=++tot;
            u=t[u][s[i]-'a'];
        }
        ++val[u];
    };
    void build() {
        for(int i=0;i<26;++i) 
            if(t[0][i]) fail[t[0][i]]=0,q.push(t[0][i]);
        while(!q.empty()) {
            int u=q.front(); q.pop();
            for(int i=0;i<26;++i) {
                if(t[u][i]) fail[t[u][i]]=t[fail[u]][i],q.push(t[u][i]);
                else t[u][i]=t[fail[u]][i]; //类似于路径压缩的优化
            }
        }	
    };
    int query(char *s) {
        int len=strlen(s),u=0,ans=0;
        for(int i=0;i<len;++i) {
            u=t[u][s[i]-'a']; //每次从大到小统计文本串以第i个字符结束的所有串
            for(int v=u;val[v]!=-1;v=fail[v]) 
                ans+=val[v],val[v]=-1; //剪枝,跳过无需再跳
        }
        return ans;
    };
}
using namespace Trie;

int main()
{
    int n; scanf("%d",&n);
    for(int i=1;i<=n;++i) 
        scanf("%s",p),ins(p);
    build();	
    scanf("%s",str); 
    printf("%d",query(str));
    return 0;
}
posted @   cloud_9  阅读(95)  评论(0编辑  收藏  举报
编辑推荐:
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
阅读排行:
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· Winform-耗时操作导致界面渲染滞后
· Phi小模型开发教程:C#使用本地模型Phi视觉模型分析图像,实现图片分类、搜索等功能
· 语音处理 开源项目 EchoSharp
· drools 规则引擎和 solon-flow 哪个好?solon-flow 简明教程
点击右上角即可分享
微信分享提示