AC 自动机_模式匹配自动机

AC 自动机_模式匹配自动机学习AC自动机的前提是要会trie数和KMP字符串匹配,它的功能是能对好多个模式串进行同时查找。比如对4个模式串:hehershisshe在一条母串中:shejjjjj查找每个模式串出现的次数.我们知道KMP算法有个next数组,和KMP类似,AC自动机有一个fail指针数组,用来对整棵trie树进行滚动。AC 自动机:HUD 3065:#i

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

学习AC自动机的前提是要会trie数和KMP字符串匹配, 它的功能是能对好多个模式串进行同时查找。

比如对4个模式串:

he

hers

his

she

在一条母串中:shejjjjj 查找每个模式串出现的次数.

我们知道KMP算法有个next数组,和KMP类似,AC自动机有一个fail指针数组,用来对整棵trie树进行滚动。

AC 自动机:

HUD 3065

#include<cstdio>

#include<cstring>

#include<queue>

using namespace std;

int ch[1002*52][26],End[1002*52],cur,fail[1002*52],last[1002*52],ans[1002];

char str[2000005],str0[1002][52];

void get_fail() {

    int now,tmpFail,Next;

    queue<int> q;

    //bfs生成fail

    //初始化队列

    for(int j=0;j<26;j++) {

        if(ch[0][j]) {

            q.push(ch[0][j]);

            fail[ch[0][j]] = 0;

            last[ch[0][j]] = 0;

        }

    }

    while(!q.empty()) {

        //从队列中拿出now

        //此时now中的faillast已经算好了

        //下面计算的是ch[now][j]中的faillast

        now = q.front();q.pop();

        for(int j=0;j<26;j++) { 

            if(!ch[now][j]) continue;

            Next = ch[now][j];

            q.push(Next);

            tmpFail = fail[now];//kjkhj

            while(tmpFail&&!ch[tmpFail][j]) tmpFail = fail[tmpFail];

            fail[Next] = ch[tmpFail][j];

            last[Next] = End[fail[Next]] ? fail[Next]:last[fail[Next]];

        }

    }

}

void Find(){

    int now = 0;

    int len = strlen(str);

    for(int i=0;i<len;i++){

        if(str[i]<‘A’||str[i]>’Z’) {now=0;continue;}

        str[i]-=’A’;

        while(now&&!ch[now][str[i]]) now = fail[now];

        now = ch[now][str[i]];

        if(End[now]) ans[End[now]]++;

        int tmp = now;

//重要理解

//这时候已经滚到了节点now,下面就需要找出所有以now为结尾的模式串,就需要用到last数组了。Last数组保存的是以节点now为结尾的模式串。

//比如 abcd  bcd  两个模式串,abcdd节点的last指向bcd中的d节点。

//当然两个d节点不是同一个。

//这样就能知道当滚到abcdd节点时,我们还同时找到了bcd这个串。

//如果存在,在找到abcd的同时,我们还找到了bcd  cd  d 这三个模式串。

//事实上,下面last数组滚过的结点,在之前可能从来没有被访问过。

//《训练指南》上的代码找的是包含模式串的一段母字符串,而不是找出所有出现过的模式串。

        while(last[tmp]) {

            ans[End[last[tmp]]]++;

            tmp = last[tmp];

        }

    }

}

int main(){

    int n,now;

    while(scanf(“%d”,&n)!=EOF){

    memset(ch,0,sizeof(ch));

    memset(End,0,sizeof(End));

    memset(ans,0,sizeof(ans));

    memset(last,0,sizeof(last));

    cur = 1;

    int len;

    for(int i=1;i<=n;i++) {

        scanf(“%s”,str0[i]);

        len = strlen(str0[i]);

        now = 0;

        for(int j=0;j<len;j++) {

            str0[i][j]-=’A’;

            if(ch[now][str0[i][j]]==0) ch[now][str0[i][j]] = cur++;

            now = ch[now][str0[i][j]];

            str0[i][j]+=’A’;

        }

        End[now] = i;

    }

    get_fail();

    scanf(“%s”,str);

    Find();

    for(int i=1;i<=n;i++) {

        if(ans[i])

            printf(“%s: %d\n”,str0[i],ans[i]);

    }

    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223028.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 2021年美赛A题思路详解

    2021年美赛A题思路详解2021年数模美赛A题思路详解题目分析思路详解由于和队友思路不一致,导致最后我的思路只算了前两问,而后几问用了我认为离题的PCA(主成分分析)的方法,我的建模思路没有得到完全实现,总体情况很不满意,特此写下这篇文章。题目分析从题目前面所提供的背景知识可以看出,C指出分解速率与菌丝伸长速率成正相关关系,我队友认为是线性关系而我认为是对数近似的关系。第二长图给了一个正比的关系,但是坐标却很容易理解错。这个moisturetrde-off不是湿度耐受性(moisturenichewidth),更

    2022年6月9日
    89
  • Fork/Join框架阅读笔记[通俗易懂]

    Fork/Join框架阅读笔记[通俗易懂]什么是Fork/Join框架Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干 个小任务,最终汇总每个小任务结果后得到大任务结果的框架。 我们再通过Fork和Join这两个单词来理解一下Fork/Join框架。Fork就是把一个大任务切分 为若干子任务并行的执行,Join就是合并这些子任务的执行结果,最后得到这个大任务的结 果。比如计算1+2+…+10000,可以分割成10个子任务,每个子任务分别对1000个数进行求和, 最终汇总这10个子任务的结果。Fork/

    2022年8月9日
    13
  • 基于时间的反向传播算法BPTT(Backpropagation through time)[通俗易懂]

    基于时间的反向传播算法BPTT(Backpropagation through time)[通俗易懂]本文介绍BPTT的原理和实现,是读“RecurrentNeuralNetworksTutorial,Part3–BackpropagationThroughTimeandVanishingGradients”的读书笔记,代码也来自于这篇文章,加了部分注释。

    2022年6月23日
    27
  • Lync Server 2013 标准版部署(四)前端拓扑发布

    Lync Server 2013 标准版部署(四)前端拓扑发布

    2021年5月27日
    127
  • Java开发经典实战!java编程培训学校排名

    Java开发经典实战!java编程培训学校排名GC概述垃圾收集(GarbageCollection)通常被称为“GC”,由虚拟机“自动化”完成垃圾回收工作。思考一个问题,既然GC会自动回收,开发人员为什么要学习GC和内存分配呢?为了能够配置上面的参数配置?参数配置又是为了什么?“当需要排查各种内存溢出,内存泄露问题时,当垃圾成为系统达到更高并发量的瓶颈时,我们就需要对GC的自动回收实施必要的监控和调节。”JVM中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生随线程而灭。栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理。它们的

    2022年7月7日
    30
  • 简述Activity生命周期「建议收藏」

    简述Activity生命周期「建议收藏」Activity显示方式Android是使用任务(Task)管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也 被称为返回栈。新活动启动进入栈,处于栈顶,当Back或finish()销毁一个活动时,栈顶的活动会出栈,前一个入栈的活动重新处于栈顶位置,显示给用户。活动状态运行状态:处于栈顶。暂停状态:不再处于栈顶但仍可见。(内存极低时系统会考虑回收这种活动)停止状态:不再处于栈顶,并且完全不可见。(系统会保存相应的状态和成员变量,但是这并不是完全可靠的,当其他地方需要内存时,处于停止状态

    2022年8月16日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号