马拉车算法详解, C++代码实现

马拉车算法详解, C++代码实现算法介绍马拉车算法是用来在一个字符串中寻找最长回文串 正着读和反着读都相同的字符串 的一种算法 该算法运用了动态规划的思想 将寻找最长回文串算法的时间复杂度降低到了线性 算法原理对于一个字符串要判断它是否为回文串要分为字符串长度为奇数或者偶数两种情况 为了简化做法 我们进行如下的操作 在字符串的两端和每两个字符中间添加一个 或者任意一个一定不会在字符串中出现的字符 通常就是 啦 再在字符串的开始和结尾放置字符串开始和结束的标识符 上述操作后拓展出来的字符串的长度一定是奇数

算法介绍

算法原理

对于一个字符串要判断它是否为回文串要分为字符串长度为奇数或者偶数两种情况,为了简化做法,我们进行如下的操作:

  1. 在字符串的两端和每两个字符中间添加一个 ‘#’ (或者任意一个一定不会在字符串中出现的字符, 通常就是 ‘#’ 啦)
  2. 再在字符串的开始和结尾放置字符串开始和结束的标识符。
    上述操作后拓展出来的字符串的长度一定是奇数。

例如:

abcd 拓展后变为 ^#a#b#c#d#$ abc 拓展后变为 ^#a#b#c#$ 
这里举个例子 s[] = "abac" str[] ^ # a # b # a # c # $ dp[] 1 2 1 4 1 2 1 2 1 
int right; // 在计算过程中用于记录寻找到所有子回文串中右边界的下标 int pos; // 用于记录右边界就是right的子回文串的下标 
 ---------------------------------------------------- ^ ^ ^ |<--------------------|-------------------->| left pos right 

如果 i 在 pos 和 right 之间,则可以寻找 i 关于 pos 的对称点,这时可以先假设dp[i] = dp[2*pos-i],这个假设并不在任何情况下都成立:
如果中心为 2*pos-i 的回文串覆盖的区域左边界超过了left,则这个回文串中存在一些可能不在中心为 i 的回文串中的元素,这种情况下dp[i] = right-i
将上述讨论的情况结合起来即可得到:
dp[i] = min(dp[2*pos-i], right-i)
如果 i > right 那我们就用暴力的方法求解dp[i]即可



算法实现

int Manacher(char* s) { 
    int len = strlen(s+1); char str[2*len+10]; int dp[2*len+10]; int cur = 0; str[0] = '^'; for(int i = 0; i < len; ++i) { 
    str[++cur] = '#'; str[++cur] = s[i]; } str[++cur] = '#', str[++cur] = '$'; int right = 0, pos = 0; for(int i = 1; i <= cur; ++i) { 
    if(i < right) dp[i] = min(dp[2*pos-i], right-i); else dp[right=i] = 1; while(str[i-dp[i]] == str[i+dp[i]]) ++dp[i]; if(i+dp[i] > right) right = i+dp[i], pos = i; } return *max_element(dp+1, dp+cur+1)-1; } 

特别感谢

感谢我女朋友对我的大力支持?。

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

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

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


相关推荐

  • dubbo入门详解[通俗易懂]

    dubbo入门详解[通俗易懂]dubbo分布式系统简介发展演变RPCdubbo核心概念搭建dubbo分布式系统简介“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”分布式系统(distributed system)是建立在网络之上的软件系统。随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。发展演变单一应用架构当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时

    2022年8月8日
    5
  • 微信开放平台—-微信扫码登录

    微信开放平台—-微信扫码登录告知:所有操作是基于域名已备案,并且具有企业级微信公众号!1.准备工作   1.1.注册微信开放平台帐号       https://open.weixin.qq.com   1.2.创建应用(网站应用),填写资料https://open.weixin.qq.com/cgi-bin/appcreate?t=manage/createWeb&amp;type=…

    2022年6月11日
    55
  • CentOS 6 命令(九)——磁盘阵列RAID

    CentOS 6 命令(九)——磁盘阵列RAIDmdadm-C/dev/md0-l5-n3/dev/sd[bcd]#创建等级为5的阵列设备md0,由sdb、sdc、sdd组成mdadm-D/dev/md0#查看阵列状态。-D查看状态pvcreate/dev/md0#将虚拟磁盘做成物理卷vgcreatenz2001_vg/dev/md0#创建卷组lvcreate-L1G-nnz2001_lv…

    2022年5月2日
    103
  • Python+opencv调用摄像头获取视频保存到本地并应用到YOLO中保存视频检测后的结果

    Python+opencv调用摄像头获取视频保存到本地并应用到YOLO中保存视频检测后的结果文章目录前言读写视频流获取摄像头:写入视频:完整的调用摄像头并保存视频代码应用到YOLO中总结前言之前的文章介绍了如何调用摄像头间隔拍照并保存图片(文章链接:Python+OpenCV调用摄像头固定间隔时间拍照并保存到本地同时应用到YOLO中检测目标),这篇文章再介绍一下如何调用摄像头并保存视频。读写视频流获取摄像头:capture=cv2.VideoCapture(0)ref,frame=capture.read()前文介绍过,cv2.VideoCapture()获取摄像头

    2022年6月22日
    30
  • 三菱plc编写最简单的梯形图演示_三菱plc梯形图实例详解

    三菱plc编写最简单的梯形图演示_三菱plc梯形图实例详解梯形图言语是一种以图形符号及图形符号在图中的彼此联络标明操控联络的编程言语,是从继电器电路图演化过来的。继电器操控电路图与plc操控的梯形图的比照梯形图与继电器操控电路图两者之间存在很多区别:(1)PLC选用梯形图编程是仿照继电器操控体系的标明方法,因而梯形图内各种元件也沿袭了继电器的叫法,称之为“软继电器”,例如X0、X1(输入继电器)、Y0(输出继电器)。梯形图中的“软继电器”不是物理继电器,…

    2025年10月25日
    2
  • oracle常用操作_oracle日志文件在哪里

    oracle常用操作_oracle日志文件在哪里如果某个oracle账户经常被锁定,说明有应用程序或有人远程连接数据库多次失败后导致账户被锁定,oracle默认是有次数限制的,可以通过以下方式解决问题:1、用管理员账户登录:connsys/sysassysdba;2、解锁账户:alteruserscottaccountunlock;3、重置账户密码:alteruserscottidentifiedbytiger;4、授权:grantresource,connecttoscott;5、修改oracle默认配置:al

    2025年7月8日
    2

发表回复

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

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