由于回文分为偶回文(比如 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. spring boot 2.0添加对fastjson的支持

    首先引入fastjson的maven依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId&g ...

  2. Yii2 注册表单验证规则 手机注册时候使用短信验证码

    public function rules() { return [ ['username', 'filter', 'filter' => 'trim'], ['username', 'requ ...

  3. ETL应用:一种一次获取一个平台接口文件的方法

    ETL应用场景中,若对端接口文件未能提供,任务会处于循环等待,直到对端提供为止,该方法极大的消耗了系统资源.为此想到了一种方法,一次获取一个平台的文件,实现思路如下: 1.第一次获取对端平台提供目录下 ...

  4. uboot相关的几篇好文

    http://www.eeworld.com.cn/mcu/2015/0727/article_21246.html http://blog.csdn.net/kernel_yx/article/de ...

  5. 【Flask】Sqlalchemy group_by having

    ### group_by:根据某个字段进行分组.比如想要根据性别进行分组,来统计每个分组分别有多少人 ### having: having是对查找结果进一步过滤.比如只想要看未成年人的数量,那么可以首 ...

  6. git 使用教程 --基础一

    第一步:下载git   https://git-scm.com/ 第二步: 切到需要保存的文件夹下,执行: bogon:VBV mona$ git init #初始化,表示即将对当前文件夹进行版本控制 ...

  7. [NOI2008]奥运物流

    题目 洛谷 BZOJ 做法 单环有向图毒瘤题 不考虑环和改变后继:\(\sum\limits{i=1}^n C_i\cdot K^{dep(i)}\) 考虑环无穷等比求极m:\(R(1)=\sum\l ...

  8. Django用户注册、邮箱验证实践

    算法流程如下:1)处理用户注册数据,存入数据库,is_activity字段设置为False,用户未认证之前不允许登陆2)产生token,生成验证连接URL3)发送验证邮件4)用户通过认证邮箱点击验证连 ...

  9. blast+简介

    blast+有三大工具类型: 功能 search database filter 命令 blastn, blastp, blastx, tblastx, tblastn, psiblast, rpsb ...

  10. 一个声明被new多次

    如果声明一个指针变量,然后为这个变量new多次, eg:Type* A: A = new Type();//1 A = new Type();//2 最后变量A指向的是最后的那个对象,与前面new的无 ...