KMP算法和Manacher算法

KMP算法

KMP算法解决的问题

KMP算法用来解决字符串匹配问题: 找到长串中短串出现的位置.

KMP算法思路

暴力比较与KMP的区别
  • 暴力匹配: 对长串的每个位,都从头开始匹配短串的所有位.
    image
  • KMP算法: 将短字符串前后相同的部分存储在 n e x t next next数组里,让之前匹配过的信息指导之后的匹配.
    image
n e x t next next数组及其求法

n e x t next next数组体现字符串某位前边子串最长匹配前缀和最长匹配后缀的匹配长度(可以有交叉). n e x t [ i ] next[i] next[i]表示第 i i i位前边的最长匹配后缀对应的最长匹配前缀的后一位.
下面是一个next数组的例子:
image

next数组的求法

n e x t next next数组的求法用到了递推思想:

  1. 0 0 0位前边没有匹配前后缀,因此 n e x t [ 0 ] = − 1 next[0]=-1 next[0]=1

  2. 1 1 1位前缀字符串的长度为1,因此 n e x t [ 1 ] = 0 next[1]=0 next[1]=0

  3. 站在第 p o s pos pos位上,就要考虑以第 i − 1 i-1 i1位结尾的最长匹配(也就是不断地求 n u m s [ p o s − 1 ] nums[pos-1] nums[pos1] n e x t [ n e x t [ . . . n e x t [ p o s − 1 ] ] ] next[next[...next[pos-1]]] next[next[...next[pos1]]]之间的关系):

image

  • c n cn cn指针指向前一个匹配后缀的下一位,即 c n = n e x t [ p o s − 1 ] cn=next[pos-1] cn=next[pos1]
  • 若前一个匹配后缀的下一位字符刚好与待匹配字符相同,即 m s [ c n ] = = m s [ p o s − 1 ] ms[cn]==ms[pos-1] ms[cn]==ms[pos1],则更新next数组,将 n e x t [ p o s ] next[pos] next[pos]指向 c n cn cn的下一位 n e x t [ p o s ] = c n + 1 next[pos]=cn+1 next[pos]=cn+1
  • 若前一个匹配后缀的下一位字符与待匹配字符不同,即 m s [ c n ] ! = m s [ p o s − 1 ] ms[cn]!=ms[pos-1] ms[cn]!=ms[pos1],则应该找前一个匹配数组,即 c n = n e x t [ c n ] cn=next[cn] cn=next[cn]
  • 若最终找到 c n = = − 1 cn==-1 cn==1也没找到,则 p o s − 1 pos-1 pos1位实在没有匹配后缀了,将其 n e x t next next数组置 0 0 0,即 n e x t [ p o s ] = 0 next[pos]=0 next[pos]=0
// 计算ms字符串的next[]数组
public static int[] getNextArray(char[] ms) {if (ms.length == 1) {return new int[] { -1 };}int[] next = new int[ms.length];next[0] = -1;	// 第0位前边没有前缀字符串,因此返回-1next[1] = 0;	// 第1位前缀字符串的长度为1,若该位匹配不上则只能去匹配首位,因此返回0// 从第2位开始,递推出后面位的next[]值for (int pos = 2; pos < ms.length; pos++) {// 一直向前找前边位的匹配前缀且该前缀的后一位与本位相同int cn = next[pos - 1];while (cn != -1 && ms[cn] != ms[pos-1]) {// 将前缀的后一位与当前位的前一位进行对比cn = next[cn];}// 判断是否能找到匹配前缀//if (cn != -1) {//	// 若能找到匹配前后缀,则返回匹配前缀的后一位//	next[pos] = cn + 1;//} else {//	// 若找不到匹配前后缀,返回-1//	next[pos] = 0;//}// 上述判断语句可以简化为一句next[pos] = cn + 1;}return next;
}

在写入 n e x t next next数组的 p o s pos pos位时要注意: 匹配前缀延伸的时候,要判断的是 m s [ c n ] 与 m s [ p o s − 1 ] ms[cn]与ms[pos-1] ms[cn]ms[pos1]之间是否相等
(因为 n e x t next next数组保存的是本位前一位的匹配前缀的下一位,因此 m s [ c n ] ms[cn] ms[cn]指向匹配前缀的下一位, m s [ p o s − 1 ] ms[pos-1] ms[pos1]指向上次计算未进行匹配的位)

题目代码
P3375 【模板】KMP
#include <bits/stdc++.h>
using namespace std;
int kmp[1000005];
int la,lb,j;
char a[1000005],b[1000005];
int main() {cin>>a+1;cin>>b+1;la=strlen(a+1);lb=strlen(b+1);for (int i=2; i<=lb; i++) {while(j&&b[i]!=b[j+1])j=kmp[j];if(b[j+1]==b[i])j++;kmp[i]=j;}j=0;for(int i=1; i<=la; i++) {while(j>0&&b[j+1]!=a[i])j=kmp[j];if (b[j+1]==a[i])j++;if (j==lb) {cout<<i-lb+1<<endl;j=kmp[j];}}for (int i=1; i<=lb; i++)cout<<kmp[i]<<" ";return 0;
}

Manacher算法

Manacher算法解决的问题

Manacher算法用来寻找字符串的最长回文子串.

回文串的相关概念

  1. 回文右边界: 当前所有回文串中,回文右边界所能到达的最右位置.
  2. 回文右边界中心: 以回文右边界结尾的最长回文串的回文中心.

Manacher算法思路

从第一位开始,遍历字符串的所有位.初始时回文右边界为-1.
image
当遍历到第pos位时,有以下两种情况

  1. p o s pos pos不在回文右边界 r i g h t B o r d e r rightBorder rightBorder以内 ( p o s > r i g h t B o r d e r ) (pos > rightBorder) (pos>rightBorder): 以该位为中心向两边暴力扩展回文串.
  2. p o s pos pos在回文右边界 r i g h t B o r d e r rightBorder rightBorder以内 ( p o s < = r i g h t B o r d e r ) : (pos <= rightBorder): (pos<=rightBorder):找到回文右边界中心 r i g h t C e n t e r rightCenter rightCenter,对应的回文左边界,以及 p o s pos pos关于回文右边界中心的对称点 p o s ′ pos' pos.这样 p o s ′ pos' pos的回文半径可以用来指导 p o s pos pos的回文半径
    1. p o s ′ pos' pos回文串关于 r i g h t C e n t e r rightCenter rightCenter的对称串在回文右边界以内 ( p o s + c u r R a d i u s [ p o s ] − 1 < = r i g h t B o r d e r ) (pos + curRadius[pos] -1 <= rightBorder) (pos+curRadius[pos]1<=rightBorder),说明 p o s pos pos的回文半径与 p o s ′ pos' pos的回文半径相同
    2. p o s ′ pos' pos回文串关于 r i g h t C e n t e r rightCenter rightCenter的对称串在回文右边界以外 ( p o s + c u r R a d i u s [ p o s ] − 1 > r i g h t B o r d e r ) (pos + curRadius[pos] -1 > rightBorder) (pos+curRadius[pos]1>rightBorder),由对称性可知,对称串超出回文右边界的部分一定不能构成以 p o s pos pos为中心的回文.因此 p o s pos pos的回文半径即为 p o s pos pos到回文右边界之间.
      在遍历过程中维护的回文右边界串并不一定是最长回文子串,如上面演示图中第一种情况为例: 遍历结束时,回文右边界串为" a b c b a abcba abcba",最长回文子串为" a b c b a d a b c b a abcbadabcba abcbadabcba"

题目代码

P3805 【模板】manacher
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=22000010;
char fr[maxn],s[maxn];
ll len[maxn];
int main()
{scanf("%s",fr);ll frlen=strlen(fr),count1=0;s[count1++]='*';for(ll i=0;i<frlen;i++){s[count1++]='#';s[count1++]=fr[i];}s[count1++]='#';s[count1++]='!';len[0]=0;ll mx=0,ans=0,id=0;for(ll i=1;i<count1;i++){if(i<mx)len[i]=min(mx-i,len[2*id-i]);elselen[i]=1;while(s[i-len[i]]==s[i+len[i]])len[i]++;if(len[i]+i>mx){mx=len[i]+i;id=i;ans=max(ans,len[i]-1);}}printf("%lld",ans);return 0;
}

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

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

相关文章

上传项目的全部依赖到maven私有仓库-nexus

背景 项目之前的私有仓库不能使用了&#xff0c;本地仓库可以&#xff0c;但是一旦clean就没了&#xff0c;所以在本地有依赖的时候可以自己搭建一个maven私有仓库然后将依赖全部上传上去 搭建&#xff1a;使用docker-compose方式搭建 docker-compose文件 version: "3…

Python算法100例-3.1 回文数

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.问题拓展7.巧用字符串技巧 1&#xff0e;问题描述 打印所有不超过n&#xff08;取n<256&#xff09;的其平方具有对称性质的数&#xff08;也称回…

在国内如何申请US,visa卡?

随着跨境与AI的发展大家对美国虚拟卡的需求也越来越多&#xff0c;比如说亚马逊、ebay、Etsy、ChatGPTPLUS、midjourney、POE等等软件以及海淘的需要&#xff0c;所以我们需要用到美国虚拟卡的场景就越来越多 如何获得一张US 虚拟信用卡&#xff1f; 方法很简单&#xff0c;点…

一线大厂软件测试面试题及答案解析,2024最强版...

【软件测试面试突击班】2024吃透软件测试面试最全八股文攻略教程&#xff0c;一周学完让你面试通过率提高90%&#xff01;&#xff08;自动化测试&#xff09; 1、什么是兼容性测试?兼容性测试侧重哪些方面? 参考答案: 兼容测试主要是检查软件在不同的硬件平台、软件平台上…

CNAN知识图谱辅助推荐系统

CNAN知识图谱辅助推荐系统 文章介绍了一个基于KG的推荐系统模型&#xff0c;代码也已开源&#xff0c;可以看出主要follow了KGNN-LS 。算法流程大致如下&#xff1a; 1. 算法介绍 算法除去attention机制外&#xff0c;主要的思想在于&#xff1a;user由交互过的item来表示、i…

OpenShift AI - 部署并使用 LLM 模型

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.15 RHODS 2.7.0 的环境中验证 文章目录 安装 OpenShift AI 环境安装 Minio 对象存储软件配置 Single Model Serving 运行环境创建项目和 Workbench准备模型和配置 Model Server访问 LLM 模…

DCTNet

DCTNet http://giantpandacv.com/academic/%E7%AE%97%E6%B3%95%E7%A7%91%E6%99%AE/%E9%A2%91%E5%9F%9F%E4%B8%AD%E7%9A%84CNN/CVPR%202020%20%E5%9C%A8%E9%A2%91%E5%9F%9F%E4%B8%AD%E5%AD%A6%E4%B9%A0%E7%9A%84DCTNet/ 一个对输入图像进行频域转换和选择的方法&#xff0c;达到…

python实现手机号归属地查询

手机上突然收到了某银行的短信提示&#xff0c;看了一下手机的位数&#xff0c;正好是11位。我一想&#xff0c;这不就是标准的手机号码吗&#xff1f;于是一个想法涌上心头——用python的库实现查询手机号码归属地查询自由。 那实现的效果如下&#xff1a; 注&#xff1a;电…

2.3_3 进程互斥的硬件实现方法

文章目录 2.3_3 进程互斥的硬件实现方法&#xff08;一&#xff09;中断屏蔽方法&#xff08;二&#xff09;TestAndSet指令&#xff08;三&#xff09;Swap指令 总结&#xff08;四&#xff09;互斥锁 2.3_3 进程互斥的硬件实现方法 学习提示&#xff1a; 1.理解各方法的原理 …

Python从0到100(二):Python语言介绍及第一个Pyhon程序

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

springcloud:3.3测试重试机制

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http:/…

UNIapp实现局域网内在线升级

首先是UNIapp 生成apk 用Hbuilder 进行打包 可以从网站https://www.yunedit.com/reg?gotocert 使用自有证书&#xff0c;目测比直接使用云证书要快一些。 发布apk 网站 用IIS发布即可 注意事项中记录如下内容 第一、需要在 iis 的MiMe 中添加apk 的格式&#xff0c;否则无法…

如何本地创建websocket服务端并发布到公网实现远程访问

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

如何实现飞书与金蝶无缝对接,提升业务效率与客户满意度?

一、客户介绍 某贸易有限公司是一家专业从事进口葡萄酒和高端烈酒销售的企业。在市场竞争日益激烈的今天&#xff0c;该公司始终坚持以客户为中心&#xff0c;以市场为导向&#xff0c;不断创新和进步。公司不仅注重传统销售渠道的拓展&#xff0c;还积极拥抱互联网&#xff0…

processing绘制笑脸

笑脸效果图&#xff1a; processing代码&#xff1a; void setup(){size(1000,1000);//Canvas sizebackground(#ffcc33);//Canvas background color } void draw(){ strokeWeight(12);//face-width12px fill(#ffffcc);//face arc(500,500,200,200,0,TWO_PI);//face-size strok…

【推荐算法系列十八】:DSSM 召回算法

参考 推荐系统中 DSSM 双塔模型汇总&#xff08;二更&#xff09; DSSM 和 YouTubeDNN 都是比较经典的 U2I 模型。 U2I 召回 U2I 召回也就是 User-to-Item 召回&#xff0c;它基于用户的历史行为以及用户的一些个人信息&#xff0c;对系统中的候选物品进行筛选&#xff0c;挑…

备考2024年上海高考数学:历年选择题真题练一练(2014~2023)

今天距离2024年高考还有三个多月的时间&#xff0c;今天我们来看一下2014~2023年的上海高考数学的选择题&#xff0c;从过去十年的真题中随机抽取5道题&#xff0c;并且提供解析。 后附六分成长独家制作的在线练习集&#xff0c;科学、高效地反复刷这些真题&#xff0c;吃透真题…

Sora爆火,数字人IP如何借助AIGC视频生成软件制作短视频营销?

ChatGPT、Sora等大模型的出现&#xff0c;创新了短视频内容创作生产方式。但目前Sora模型无法准确模拟复杂场景的物理特性&#xff0c;并且可能无法理解因果关系导致视频失真。 广州虚拟动力基于用户使用需求&#xff0c;推出了AIGC数字人视频生成平台&#xff0c;企业、品牌可…

Android MediaCodec 简明教程(五):使用 MediaCodec 编码 ByteBuffer 数据,并保存为 MP4 文件

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…

每日一练:LeeCode-707. 设计链表 【链表+虚拟头结点+设计】

每日一练&#xff1a;LeeCode-707. 设计链表 【链表虚拟头结点设计】 思路设置虚拟头节点 本文是力扣 每日一练&#xff1a;LeeCode-707. 设计链表 【链表虚拟头结点设计】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode-70…