zoukankan      html  css  js  c++  java
  • [模板][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;
    }
    
  • 相关阅读:
    C#成员设计建议
    基于任务的异步编程模式(TAP)的错误处理
    基于任务的异步编程模式(TAP)
    C#克隆
    C#操作excel打印
    父元素如何围住浮动子元素
    intellij idea创建第一个动态web项目
    Idea快捷键
    Python中列表的copy方法
    C++读取数量不定的数据
  • 原文地址:https://www.cnblogs.com/list1/p/10382849.html
Copyright © 2011-2022 走看看