由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里)。举个例子:s="abbahopxpo",转换为s_new="$#a#b#b#a#h#o#p#x#p#o#"(这里的字符 $ 只是为了防止越界,下面代码会有说明),如此,s 里起初有一个偶回文abba和一个奇回文opxpo,被转换为#a#b#b#a##o#p#x#p#o#,长度都转换成了奇数。
  定义一个辅助数组int p[]p[i]表示以s_new[i]为中心的最长回文的半径,例如:

i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
s_new[i] $ # a # b # b # a # h # o # p # x # p #
p[i]   1 2 1 4 5 2 1 2 1 2 1 2 1 2 1 6 1 2 1

可以看出,p[i]-1正好是原字符串中最长回文串的长度。
  Manacher 算法之所以快,就快在对 p 数组的求法上有个捷径,看下图:


  设置两个变量,mx 和 id 。
  mx 代表以s_new[id]为中心的最长回文最右边界,也就是mx=id+p[id]
  假设我们现在求p[i],也就是以s_new[i]为中心的最长回文半径,如果i<mx,如上图,那么:

 if (i < mx)
p[i] = min(p[2 * id - i], mx - i);

2 * id -i其实就是等于 j ,p[j]表示以s_new[j]为中心的最长回文半径,见上图,因为 i 和 j 关于 id 对称,我们利用p[j]来加快查找。

代码:

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std; char s[];
char s_new[];
int p[]; int Init()
{
int len = strlen(s);
s_new[] = '$';
s_new[] = '#';
int j = ; for (int i = ; i < len; i++)
{
s_new[j++] = s[i];
s_new[j++] = '#';
} s_new[j] = '\0'; //别忘了哦 return j; //返回s_new的长度
} int Manacher()
{
int len = Init(); //取得新字符串长度并完成向s_new的转换
int maxLen = -; //最长回文长度 int id;
int mx = ; for (int i = ; i < len; i++)
{
if (i < mx)
p[i] = min(p[ * id - i], mx - i); //需搞清楚上面那张图含义, mx和2*id-i的含义
else
p[i] = ; while (s_new[i - p[i]] == s_new[i + p[i]]) //不需边界判断,因为左有'$',右有'\0'
p[i]++; //我们每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率
if (mx < i + p[i])
{
id = i;
mx = i + p[i];
} maxLen = max(maxLen, p[i] - );
} return maxLen;
} int main()
{
while (printf("请输入字符串:\n"))
{
scanf("%s", s);
printf("最长回文长度为 %d\n\n", Manacher());
} return ;
}

马拉车——Manacher一篇看上去很靠谱的理解(代码显然易懂)的更多相关文章

  1. Maven系列第6篇:生命周期和插件详解,此篇看过之后在maven的理解上可以超越同级别90%的人!

    maven系列目标:从入门开始开始掌握一个高级开发所需要的maven技能. 这是maven系列第6篇. 整个maven系列的内容前后是有依赖的,如果之前没有接触过maven,建议从第一篇看起,本文尾部 ...

  2. 回调函数通俗解析(之前看了很久都不理解,今天终于ok啦)

    自学jquery的时候,看到一英文词(Callback),顿时背部隐隐冒冷汗.迅速google之,发现原来中文翻译成回调.也就是回调函数了.不懂啊,于是在google回调函数,发现网上的中文解释实在是 ...

  3. HDU - 3068 最长回文(马拉车Manacher)题解

    思路:马拉车裸题,我们用一个p[i]数组代表以i为中心的最大回文半径.这里用了一个小技巧,如果一个串是aaaa这样的,那我们插入不相干的字符使它成为#a#a#a#a#,这样无论这个串是奇数还是偶数都会 ...

  4. 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 百篇博客分析OpenHarmony源码 | v41.03

    百篇博客系列篇.本篇为: v41.xx 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁 ...

  5. x01.os.15: 看上去很美

    张碧晨在韩国学的不是技巧,而是基本功:气息!声音由气息托着,似真声而不是真声,似假声又不是假声,所以才能在动听的地方唱得更动听.编程也是一样,基本功很重要:内存!所谓的黑客高手,攻击的一大手段,便是利 ...

  6. 看上去很美 国内CDN现状与美国对比

    CDN的理想与现实 多年以前,当<Kingdom of Heaven>这部史诗电影发行的时候,中国的影迷使用电驴和BT来寻找种子,而那个时候,高清也才刚刚进入电影领域,我的同事不惜用自家的 ...

  7. 你只是看起来很努力(只是做了一遍真题,草草的对了一遍答案,然后冲出自习室继续她学生会的事情了,骗自己更容易)good——想起了自己在六大时候的无奈

    (转)你只是看起来很努力一次上课,一个女孩子垂头丧气的跟我说,老师,我考了四次四级,还没过,究竟是为什么. 我说,你真题做了吗?单词背了吗?她拿出已经翻破了的真题,跟我说,你讲的所有的题目我连答案都记 ...

  8. Spring Boot 揭秘与实战(四) 配置文件篇 - 有哪些很棒的特性

    文章目录 1. 使用属性文件2. YAML文件 1.1. 自定义属性 1.2. 参数引用 1.3. 随机数属性 1.4. application-{profile}.properties参数加载 3. ...

  9. 美国诚实签经验——中英文行程单、往返机票、用英语面试的申请者通过率>用中文面试的申请者的通过率、一直保持着微笑,看上去很自信,也很诚恳、户口簿带上最好

    在排队等待时据我的观察,用英语面试的申请者通过率>用中文面试的申请者的通过率.一家人申请通过率>单个人通过率:商务签证通过率>旅游签证通过率 一.    面签材料 1.    必备材 ...

随机推荐

  1. tensorflow 张量的阶、形状、数据类型及None在tensor中表示的意思。

    x = tf.placeholder(tf.float32, [None, 784]) x isn't a specific value. It's a placeholder, a value th ...

  2. 基于nodejs的wiki系统

    jingo:        https://github.com/claudioc/jingo nodewiki:    https://github.com/nhoss2/nodewiki Tidd ...

  3. Python3 optparse模块

    Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...

  4. iOS 反射 学习 和 运用

    iOS  反射 学习 和 运用 反射:  通过 类名来获得生成的相应的类的实例 的这种机制  叫 反射 常用的反射方式 把 NSDictionary  转成 自定义 model 自定义 model 转 ...

  5. classpath是什么

    作用: 告诉Java执行环境,在哪些目录下可以找到您所要执行的Java程序所需要的类或者包(也就是.class文件) JDK 5.0默认就会到JDK的lib目录下寻找Java程序. 如何配置? 有许多 ...

  6. PHP常用函数的归纳

    //===============================时间日期=============================== //y返回年最后两位,Y年四位数,m月份数字,M月份英文.d月 ...

  7. git基础一

    礼节为上: 从这次的武昌砍人时间分析:一定要对别人客气一点,无论在餐厅,或者任何事情上面一定要对别人客气 即使自己遇到很烦心的事情,也要保持情绪,因为如果遇到神经病,刚好自己没有控制好自己的情绪,自己 ...

  8. 2.3UML建模之用例图关系

    一.UML简介 UML(统一建模语言,Unified Modeling Language)是一种定义良好.易于表达.功能强大且普遍适用的可视化建模语言.它融入了软件工程领域的新思想.新方法和新技术.它 ...

  9. 在Linux系统下使用Docker以及Weave搭建Nginx反向代理

    Hi, 今天我们将会学习如何使用 Weave 和 Docker 搭建 Nginx 的反向代理/负载均衡服务器.Weave 可以创建一个虚拟网络将 Docker 容器彼此连接在一起,支持跨主机部署及自动 ...

  10. spark总结4 算子问题总结

    官网上最清晰 sc 启动spark时候就已经初始化好了 sc.textFile后 会产生一个rdd spark 的算子分为两类 一类 Transformation  转换 一类 Action  动作 ...