(K)MP有限状态自动机

模式匹配自动机

什么是有限状态自动机?
定义 n 个不同状态,记为 {1,2…n},在状态 i 时输入 s,达到状态 j,记为 goto (i,s)=j
对于字符串 s 而言,在一个状态 i 下输入一个字符 ch,也会达到一个指定状态 :
假定新的状态为串 s [1,i]+ch 的最长相等前后缀 ,便能够用这个状态机模拟 KMP 算法匹配字符串的过程。
当字符集仅为 a、b 时,有:


其中 goto (4,a)=3,也就是说 abab+a 的最长相等前后缀 对应的状态是状态 3 ,也即表示字符串 “aba” 的状态。
似乎这样就足够了。
我们获得了 goto 函数,定义为:

goto (Si,a):串 s [1,i] a 的最长相等前后缀。

为了得到这个 goto 函数的值,我们需要定义 fail 函数:

fail (Si): 串 s [1,i] 的最长相等前后缀。

因为得到 goto (i,a) 的前提是,知道 s [1,i] 的最长相等前后缀 s\[1,j] :若 s [j+1] 与 a 相同,则 goto (i,a)=j+1,否则求 s [1,j] 的最长相等前后缀,直到长度为 0。
为了表示 “s [j+1] 与 a 相同” 这一条件,定义函数:

follow (Si, a): 状态 Si 输入 a 后,来到下一个状态。

对于字符串 abcde,follow (0,a)=1,follow (1,b)=2,follow (2,c)=3… 以此类推,而其他值未定义。
到这里,goto 函数就可表示为:

state go_to(state s,char ch){while(follow(s,ch)未定义){s=fail[s];}return follow(s,ch);
}

若 s 为模式串的状态,ch 为 s 的后继字符,则这一 goto 值可当做新的 fail 值。

未定义状态,比如 follow (0,b), 计为 0 可不可行?
与之配套地,fail (0), 计为 0,也就是说空串的最长相等前后缀长度 为 0。
若 fail (0) 记为 - 1,则 follow (s==-1,ch) 将陷入故障状态:没有状态被记为 - 1。
问题出现了!函数不得不进入死循环:因为 s 一直为 0。
破环方式也很简单:

引入状态 - 1,未定义状态记为 - 1,fail (0)=-1,follow (-1, 任何字符)=0。

这样,当计算 ab+c 的最长相等前后缀 时,便能够得到 go_to (2,c)=0。
类似地,计算fail数组的函数为:

Compute_fail()
{fail(s0) = ⊥;s = s0;for( i =1 to |P| ){s = goto(s, P[i]);fail(si) = s ;}
}

goto 和 fail 数组的关系:fail 反映模式串中的某部分字符串的最长相等前后缀 ,goto 反映文本串和模式串的匹配情况。诚然,fail 数组可以通过 goto 函数得到,但记录一些中间状态有利于加速算法。

匹配函数:

Match(t)
{s= s0;for(int i=1 to |T|){if( s 是终止状态 )return 匹配!else  s=goto(s,T[i]);}
} 

MP 有限状态自动机

我们都知道 mp 的 c++ 写法。
基于以上定义,我们艰难地知道 mp 的有限状态自动机写法:

#include<bits/stdc++.h>
using namespace  std;
#define state int
string P; //模式串
string T;
state fail[1000005];
state edge[1000005][26];state follow(state s,char ch){if(s==-1) return 0;if(edge[s][ch-'A']==s+1) return s+1;return -1;
}
state go_to(state s,char ch){while(follow(s,ch)==-1){s=fail[s];}return follow(s,ch);
}void get_fail(){fail[0]=-1;state s_=0;for(int i=1;i<P.size();i++){s_=go_to(s_,P[i]);fail[state(i)]=s_;if(fail[s_]!=-1&&P[s_+1]-'A'==P[i+1]-'A'){fail[state(i)]=fail[s_];}//!!!K优化!!!edge[i-1][P[i] - 'A'] = i;}
}
void match(){state s_=0;for(int i=1;i<T.size();i++){s_=go_to(s_,T[i]);if(s_==state(P.size()-1)){cout<<i-P.size()+2<<endl;}}
}
signed main() {cin>>T>>P;P=" "+P;T=" "+T;get_fail();match();for(int i=1;i<P.size();i++){cout<<fail[i]<<" ";
}}

洛谷提交情况如下: 洛谷
这是一种没有任何实战意义的写法。
需要注意俩点:

if(edge[s][ch-‘A’]==s+1) return s+1;

只有计算 fail 函数时,遍历过某个字符时,才连一条 edge 边。
也就是说,在未遍历时,字符串 abc 的 follow (0,a)=-1,follow (1,b)=-1,follow (1,c)=-1, 而当遍历 b 时,follow (0,a)=1,follow (1,b)=2,follow (1,c)=-1。这样做的原因是,若模式串天然有 follow 边,则 fail 数组的值会依次为 - 1,1,2,3,4…

if(fail[s_]!=-1&&P[s_+1]-‘A’==P[i+1]-‘A’){
fail[state(i)]=fail[s_]; }

这是 knuth 优化。对于字符串 aaaa,mp 的 fail 数组是 0,1,2,3 而 kmp 的 fail 数组是 0,0,0,3。
因为 kmp 的 fail 数组不能很好地反映字符串的前后缀的关系,而我们通常需要利用这种关系,故现常用 mp,且把 mp 称为 kmp。

MP 算法是一个 O (m+n) 的算法,证明如下:

1. 在 check 函数中,对文本串扫描一遍,无回头扫描,消耗 O (n)
2. 自动机向右的移动距离 >= 向左移动的距离 >= 调用 fail 的次数,而向右的移动距离 = 对文本串扫描的距离 = n,故调用 fail 的次数 = O (n)
3. 构造 fail 数组时,向右的移动距离 = 对模式串扫描的距离 = m,即 Fail 构造复杂度的复杂度为 O (m)

综合为 O (m+n)。实际上,除了 aaab 匹配 aaaaaaaa 这种极端数据外,mp 和暴力算法复杂度接近:随机情况下,暴力的复杂度也接近 O (m+n),在数据随机生成的情况下,暴力匹配也基本很快就会失配。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssh连接慢的问题或zookeeper远程连接服务超时

问题原因&#xff1a; 在SSH登录过程中&#xff0c;服务器会通过反向DNS查找客户端的主机名&#xff0c;然后与登录的IP地址进行匹配&#xff0c;以验证登录的合法性。如果客户端的IP没有域名或DNS服务器响应缓慢&#xff0c;这可能导致SSH登录过慢。为了解决这个问题&#xf…

尤雨溪都打赏的虚拟列表组件,到底有多强

尤雨溪都打赏的虚拟列表组件&#xff0c;到底有多强&#xff1f; 在前端开发中&#xff0c;性能优化永远是绕不开的主题。今天就带你看看 vue-virtual-scroller&#xff0c;一款让你滚动页面时流畅得像火箭一样的 Vue 组件。本文将简单介绍这个组件的主要功能、技术特点&#x…

JavaWeb合集07-MyBatis

七、MyBatis MyBatis是一款优秀的持久层&#xff08;dao&#xff09;框架&#xff0c;用于简化JDBC的开发。 MyBatis本是Apache的一个开源项目iBatis, 2010年这个项目由apache迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。 官网&#xff1a;https://mybati…

Axure重要元件三——中继器查询和统计

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 本节课&#xff1a;中继器查询页数 课程内容&#xff1a;查询中继器页面、自动统计页数、自动统计数据条数、上一页下一页 应用场景&#xff1a;表单的查询、表单的基本…

10秒钟用Midjourney画出国风味的变形金刚

上魔咒 Optimus Prime comes from the movie Transformers, Chinese style, Wu ShanMing, Ink Painting Halo Dyeing, Conceptual of the Digita Art, MasterComposition, Romantic Ancient Style, Inspired by traditional patterns and symbols, Minimalism, do not con…

【数据分享】全国资源和环境-环境污染治理投资(1998-2021年)

数据介绍 一级标题指标名称单位指标解释资源和环境环境污染治理投资总额亿元环境污染治理投资指在污染源治理和城市环境基础设施建设的资金投入中&#xff0c;用于形成固定资产的资金&#xff0c;其中污染源治理投资包括工业污染源治理投资和“三同时”项目环保投资两部分。环…

ssm基于SSM的社区管理系统+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 [2 系统…

1.2024.10.17

2024.10.17 总体规划 总体规划 写这个合集的原因 记录自己入行之前成长过程。本人菜鸟一枚&#xff0c;大佬不喜勿喷。 目前的规划 更新频率 尽量一天一更&#xff0c;会更新之前发布的笔记&#xff0c;争取笔记更加完善。 学习方法 目标 通过面试&#xff0c;成功入行嵌…

Tailwind css系列教程(三)

vue3环境搭建Tailwind CSS 1、创建vue3项目 创建项目&#xff1a;npm create vitelatest vue3app01 --template vue 进入项目文件夹&#xff1a;cd vue3app01 加载默认库&#xff1a;npm install 测试运行&#xff1a;npm run dev 2、搭建tailwind css &#xff08;1&a…

2010年国赛高教杯数学建模C题输油管的布置解题全过程文档及程序

2010年国赛高教杯数学建模 C题 输油管的布置 某油田计划在铁路线一侧建造两家炼油厂&#xff0c;同时在铁路线上增建一个车站&#xff0c;用来运送成品油。由于这种模式具有一定的普遍性&#xff0c;油田设计院希望建立管线建设费用最省的一般数学模型与方法。   1. 针对两炼…

在线考试系统的现代化解决方案:Spring Boot与JavaWeb

3系统分析 3.1可行性分析 通过对本基于JavaWeb技术的在线考试系统设计与实现实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于JavaWeb技术的在线考试系统设…

10 排序算法:冒泡排序与快速排序(算法原理、算法实现、时间和空间复杂度分析)

目录 1 十大常见的排序算法 1.1 算法的稳定性 2 冒泡排序 2.1 算法原理 2.2 算法实现 2.3 时间空间复杂度分析 2.3.1 时间复杂度分析 2.3.2 空间复杂度分析 3 快速排序 3.1 算法原理 3.1.1 排序思想 3.1.2 递归过程 3.2 示例 3.2.1 示例 1 3.2.2 示例 2 3.2.3 …

JAVA 中系统相关的类

System 类 代表的是当前 Java 程序运行的平台&#xff08;操作系统&#xff09;&#xff0c;该类被关键字 final 修饰&#xff0c;即该类不能够派生子类&#xff0c;同时该类的构造器被关键字 private 修饰&#xff0c;因此不能够创建 System 类型的实例对象。 System 类中定…

【数据采集工具】Sqoop从入门到面试学习总结

国科大学习生活&#xff08;期末复习资料、课程大作业解析、大厂实习经验心得等&#xff09;: 文章专栏&#xff08;点击跳转&#xff09; 大数据开发学习文档&#xff08;分布式文件系统的实现&#xff0c;大数据生态圈学习文档等&#xff09;: 文章专栏&#xff08;点击跳转&…

SpringBoot整合Freemarker(一)

Freemarker和jsp一样是一个视图的引擎模板&#xff0c;其实所有的模板引擎的工作原理都是类似的&#xff0c;如下图&#xff1a; 接下来就具体讲解一下Freemarker的用法&#xff0c;参考手册&#xff1a;模板 数据模型 输出 - FreeMarker 中文官方参考手册 SpringBoot默认就…

Agentic RAG(基于智能体的检索增强生成)是检索增强生成(Retrieval-Augmented Generation,RAG)技术的一种高级形式

Agentic RAG&#xff08;基于智能体的检索增强生成&#xff09;是检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术的一种高级形式&#xff0c;它通过引入人工智能代理&#xff08;Agent&#xff09;的概念&#xff0c;为语言模型赋予了…

中国科学院大学与美团发布首个交互式驾驶世界模型数据集DrivingDojo:推进交互式与知识丰富的驾驶世界模型

中国科学院大学与美团发布首个交互式驾驶世界模型数据集DrivingDojo&#xff1a;推进交互式与知识丰富的驾驶世界模型 Abstract 驾驶世界模型因其对复杂物理动态的建模能力而受到越来越多的关注。然而&#xff0c;由于现有驾驶数据集中的视频多样性有限&#xff0c;其卓越的建…

简述RESTFul风格的API接口

目录 传统的风格API REST风格 谓词规范 URL命令规范 避免多级URL 幂等 CURD的接口设计 REST响应 响应成功返回的状态码 重定向 错误代码 客户端 服务器 RESTful的返回格式 返回格式 从上一篇文章我们已经初步知道了怎么在VS中创建一个webapi项目。这篇文章来探讨一…

外包干了2个月,技术明显退步

回望过去&#xff0c;我是一名普通的本科生&#xff0c;于2019年通过校招有幸加入了南京某知名软件公司。那时的我&#xff0c;满怀着对未来的憧憬和热情&#xff0c;投入到了功能测试的岗位中。日复一日&#xff0c;年复一年&#xff0c;转眼间&#xff0c;我已经在这个岗位上…

牵手App红娘来助力,打造线上交友“好管家”

线上交友以其便捷性、广泛性和互动性等特点&#xff0c;正逐渐成为单身男女寻找恋爱伴侣的重要渠道。相较于传统相亲模式&#xff0c;线上交友不仅打破了时间和空间的限制&#xff0c;更以其丰富的互动功能和个性化的匹配算法&#xff0c;为用户提供了前所未有的交友体验。在这…