http://hi.baidu.com/735612658gfy/blog/item/f88114d526dc39bdcc1166db.html

http://acm.uestc.edu.cn/bbs/read.php?tid=3258

回文串可以分为两种情况,一种是长度为奇数如abcba,另一种是偶数的串,如abba。这样就为解决问题带来了不便,处理的时候需要分类讨论,为了避免这种情况,一种巧妙地方法就是对这中串进行处理,在每个字符前加一个‘#’,而第一个字符另赋值一个字符,如‘$’。这样,回文串的个数就都为奇数个了,如 ababcbaba就成了#a#b#c#b#a#,abba就成了#a#b#b#a#,然后用一个辅助数组rad记录以每个字符为中心的最长回文串的信息,rad[i]表示回文的半径,而rad[i]-1即为以str[i]为中心的回文字串在原串中的长度

原串: w aa bwsw f d
新串: # w # a # a # b # w # s # w # f # d #
辅助数组rad: 1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1

在网上看到别人的总结

我们规定p[i]是从第i个字符开始回文的半径。其实以这个字符在原来串的回文个数就是p[i]-1;

当我们求p[i]时,在i之前的p【j】是求出的,我们记录了mx=max(p【j】+j)。

当i<ma时。p【i】=min(p[2*j-i],ma-i);每次这个时间是O(1)的。

几个例题:

参见:

最长回文子串模板,Manacher算法,时间复杂度 O(n)

//hdu3068
View Code

#include<iostream>#include<cstdio>#include<stdio.h>#include<math.h>#include<cstring>using namespace std;

#define M 20000050

char str1[M],str[2*M];int rad[M],nn,n;

void Manacher(int *rad,char *str,int n)

//*str是这样一个字符串(下标从1开始)://举例:若原字符串为"abcd",则str为"$#a#b#c#d#",最后有个终止符.//n为str的长度,若原字符串长度为nn,则n=2*nn+2;//rad[i]表示回文的半径,即最大的j满足str[i-j+1……i]=str[i+1……i+j],//而rad[i]-1即为以str[i]为中心的回文字串在原串中的长度{int i;int mx=0;int id;for(i=1;i<n;i++)    {if(mx>i)            rad[i]=rad[2*id-i]<mx-i?rad[2*id-i]:mx-i;else            rad[i]=1;for(;str[i+rad[i]]==str[i-rad[i]];rad[i]++);if(rad[i]+i>mx)        {            mx=rad[i]+i;            id=i;        }    }}

int main(){int i,ans;while(scanf("%s",str1)!=EOF)    {        nn=strlen(str1);        n=2*nn+2;        str[0]='$';for(i=0;i<=nn;i++)        {            str[2*i+1]='#';            str[2*i+2]=str1[i];        }        Manacher(rad,str,n);        ans=1;for(i=0;i<n;i++)            ans=rad[i]>ans?rad[i]:ans;        printf("%d\n",ans-1);    }return 0;}



如果不用词算法,可以就奇偶分情况计算
View Code

#include<cstdio>#include<iostream>#include<cstring>using namespace std;

#define N 5010

char buf[N],s[N];int p[N];

int main(){int i,j,m,len,max,x,y,T;    scanf("%d",&T);    getchar();while(T--)    {        gets(buf);        len=strlen(buf);//p里面存储的是转换为大写字母并且去掉不是字母后的字符串中个字符对应原串的下标        for(i=0,m=0;i<len;i++)        {if(isalpha(buf[i]))//判断是否为a,b,c....这样的字母            {                s[m]=tolower(buf[i]);                p[m++]=i;            }        }        max=0;for(i=0;i<m;i++)        {//奇数时,每次向外扩展长度为1,即j+1,则向外扩展了两个字符,故为2*j,再加上中间点,所以是2*j+1            for(j=0;i-j>=0&&i+j<m;j++)            {if(s[i-j]!=s[i+j])break;if(j*2+1>max)                {                    max=j*2+1;                    x=p[i-j];                    y=p[i+j];                }            }//若为偶数时,则中间点有两个,即:当前字符及其下一个字符,故为2*j+2;            for(j=0;i-j>=0&&i+j+1<m;j++)            {if(s[i-j]!=s[i+j+1])break;if(j*2+2>max)                {                    max=j*2+2;                    x=p[i-j];                    y=p[i+j+1];                }            }        }for(i=x;i<=y;i++)            printf("%c",buf[i]);        printf("\n");    }return 0;}

/*
只需每次枚举回文字符串的“中间位置”i,然后不断往外扩展,直到有字符不同。
提示:长度为奇数和偶数的处理方式不一样。具体点是  每次以字符串中当前字母为中间点,向外扩展。
若为奇数,则以此处一个字符为中间点向外扩展,若为偶数,则以此点及其下一点为中间点向外扩展。
*/

转载于:https://www.cnblogs.com/pcoda/archive/2012/03/23/2413712.html

Manecher算法相关推荐

  1. manecher算法 最长回文子字符串

    还没放假的时候就知道有这么一种算法,之前看了一下以为很难就没好好学,今天早上用心看了一下,发现其实很简单.学什么东西都应该静下心来好好理解好好学,才能保证高效率! 我主要是看这篇博客学的马拉车,我觉得 ...

  2. 【字符串】manacher算法

    Definition 定义一个回文串为从字符串两侧向中心扫描时,左右指针指向得字符始终相同的字符串. 使用manacher算法可以在线性时间内求解出一个字符串的最长回文子串. Solution 考虑回 ...

  3. golang通过RSA算法生成token,go从配置文件中注入密钥文件,go从文件中读取密钥文件,go RSA算法下token生成与解析;go java token共用

    RSA算法 token生成与解析 本文演示两种方式,一种是把密钥文件放在配置文件中,一种是把密钥文件本身放入项目或者容器中. 下面两种的区别在于私钥公钥的初始化, init方法,需要哪种取哪种. 通过 ...

  4. 通用解题法——回溯算法(理解+练习)

    积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...

  5. 伍六七带你学算法 进阶篇-生命游戏

    有趣的算法题–生命游戏 难度-中等 根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 想要体验生命游戏的小伙伴可以到这里-->生命游戏 进入 ...

  6. 伍六七带你学算法 进阶篇-排序算法

    给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...

  7. 伍六七带你学算法 入门篇-卡牌分组

    力扣-914. 卡牌分组 难度-简单 这是一道非常有趣的题,提交通过率令人深思 ,思考它是不是一道简单的题- 开始正题: 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以 ...

  8. 伍六七带你学算法 入门篇-最小的k个数

    java面试题-最小的k个数 难度-简单 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:a ...

  9. 十大算法,描述+代码+演示+分析+改进(赶紧收藏!)

    十大算法 1.冒泡排序 ​ (1)算法描述 ​ 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作是重复地进行直到没有再需要 ...

  10. 人工智能3d建模算法_打破国外垄断,全国产3D芯片为机器人“点睛”

    ◎ 科技日报记者 崔爽 传统机器人只有"手",只能在固定好的点位上完成既定操作,而新一轮人工智能技术大大推动了机器和人的协作,这也对机器人的灵活性有了更高要求. 要想像人一样测量. ...

最新文章

  1. 50万高奖金!2022年第一场赛事来了
  2. JS中调用本地Winform程序并传递参数
  3. 为PHP开发C语言扩展
  4. D3js(一): d3js和DOM
  5. 京东智联云分布式低延时RTC系统
  6. char **p, char a[16][8]; 问:p=a 是否会导致程序在以后出现问题?为什么?
  7. 【汇编语言】8086汇编,快速搞定各种寻址方式:立即数寻址 / 寄存器寻址 / 存储器寻址
  8. 前端学习(3255):react中动态初始化结果
  9. QT:为项目生成pro文件及中文显示乱码问题
  10. sqlserver 查询一个表的所有字段代码
  11. GPS/BDS:LAC区域码和CELLID移动基站ID
  12. 【软考 系统架构设计师】软件工程⑥ 软件系统建模
  13. EAS中没有的核算项目新增
  14. 论文解读:Unprocessing Images for Learned Raw Denoising
  15. 盘点一下CSGO职业选手-光辉背后的悲情故事
  16. tp5.0 think-queue 消息队列
  17. 自媒体视频去水印工具哪个好
  18. Go语言入门到实战——14.Go语言的协程机制以及并发机制
  19. 《Excel视频9》布尔值、and or
  20. Flip Flop和DoOnce

热门文章

  1. 可展开的UITableViewCell
  2. Spring Framework标记库初学指南
  3. linux下安装redis-cli
  4. 大并发服务器不得不说的技术--TCP_CORK
  5. webpack 保存文件后自动打包_Webpack轻松入门(二)——CSS打包
  6. redis copy-on-write机制
  7. java多台_java多态
  8. BlockingQueue使用详解以及测试代码
  9. linux 无法启动vnc_ECS 云服务器 VNC篇
  10. 【渝粤教育】电大中专跨境电子商务理论与实务 (30)作业 题库