马拉车算法详解, 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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Android怎么查看手机中的本地数据库

    Android怎么查看手机中的本地数据库我前几天做的项目中有本地数据库,所以就用的SQLite,在调试数据库时,,很想看一下里面的表结构是否正确,这个时候就十分苦恼,因为这个db文件不能够直接拿出来,我们知道,在DDMS里面有一个FileExplorer,它里面保存着手机中的各个文件夹,但是尝试打开里面的文件夹的时候,却发现怎么点都没有东西,于是我就十分不解,明明我写了数据库,为什么没找到这个文件呢?后来发现其实是没有权限。下面需要注意…

    2022年5月31日
    42
  • 防止自己服务器变矿机的软件_服务器被挖矿了怎么办

    防止自己服务器变矿机的软件_服务器被挖矿了怎么办0x00背景周一早上刚到办公室,就听到同事说有一台服务器登陆不上了,我也没放在心上,继续边吃早点,边看币价是不是又跌了。不一会运维的同事也到了,气喘吁吁的说:我们有台服务器被阿里云冻结了,理由:对外恶意发包。我放下酸菜馅的包子,ssh连了一下,被拒绝了,问了下默认的22端口被封了。让运维的同事把端口改了一下,立马连上去,顺便看了一下登录名:root,还有不足8位的小白密码,心里一凉:被…

    2022年9月26日
    5
  • pi可以卸载重新安装吗_pip删除安装包

    pi可以卸载重新安装吗_pip删除安装包打开python安装目录下的Scripts文件夹,在空白处shift+鼠标右键,选择在此处打开命令窗口,在弹出的窗口中执行命令easy_install.exepip即可。如果python安装目录下的Scripts目录中有没有easy_install.exe参见http://blog.csdn.net/la6nf/article/details/7…

    2022年10月19日
    2
  • Apache的安装_Ubuntu安装Apache

    Apache的安装_Ubuntu安装Apache(一)apache介绍  ApacheHTTPServer(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,Apache也叫万维网,www服务器, web服务器主要功能是提供网上信息浏览服务。Apache可以在大多数计算机操作系统中运行,由于其多平台和安全性被广泛使用,是最流行的Web服务器端软件之一。     目前主流的Web服务器软件包括:Apache,Ngi…

    2025年11月13日
    4
  • 回调函数的理解

    回调函数的理解回调函数的理解

    2022年4月24日
    35
  • 数据库中的多表查询总结[通俗易懂]

    数据库中的多表查询总结[通俗易懂]数据库在单个表里操作其实很简答,但是涉及在多张表里寻找数据的时候,难度会大大增加,这里解释一些多表联合查询常用的操作。一、join操作在数据库的查询中,多表连接查询是一大难点,也是多表查询里的重点。连接主要有以下四种情况:INNERJOIN(内连接):如果表中有至少一个匹配,则返回行【在语法中可以省略INNER关键字】LEFTJOIN(左连接):从左表返回所有的行,如果右表中…

    2022年5月3日
    47

发表回复

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

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