manacher算法
来源:互联网 发布:python unpack修饰符 编辑:程序博客网 时间:2024/05/29 05:52
一种很有趣的算法,为什么这么说呢,因为它的预处理很巧妙。
它通常是用来求一个字符串的回文串的长度的。下面介绍一下它的大致思路。(先介绍思路再说为什么会有这种思路)
1.特殊处理字符串,把字符串的所有字符用一个没有出现过的标识隔开,并特殊标识字符串的头:
如aabb\0处理后就可以为$#a#a#b#b#\0如aabaa\0处理后就可以为$#a#a#b#a#a#\0
for(int i=strlen(s);i>=0;i--){ s[i*2+2]=s[i]; s[i*2+1]='#'; } s[0]='$';
2.设立变量maxn记录目前找寻的所有回文串中能涉及的最右端位置,设立变量id记录它所对应的对称轴的位置(大家会发现,经过处理的字符串只会存在奇数的回文串!),
用数组p[i]来记录中心为i的时候回文串长度。
int id=0,maxn=0;3.从s[1]开始,顺序处理这个字符串(s[0]被标识成$了)
for(int i=1;i<=len*2+1;i++)
4.那么在这个循环内要干什么呢?首先当然要做的是判断当前你所判断的回文串是否完全在回文串id里面。
如何判断呢?我们还是举例吧
$#d#a#b#a#e#a#b#a#d#
大家看这个字符串我们会发现,这个字符串是关于e完全对称的
假设此时id是10,maxn是19(最长的回文串),i的位置是14。
那么有没有必要从新找一下i的回文串长度呢?是没有必要的,因为,我们可以轻易的发现p[id-(i-id)]是和p[i]对称的,因此p[id-(i-id)]的长度就是p[i]的长度了!
真的是如此吗?
看下面这个数据:
$#e#a#b#a#e#a#b#a#d#
p[id-(i-id)]是要比p[i]要大一位的,这是为什么呢?因为最右边的字母和最左边的字母是不匹配的啊。
还有另外一种情况是什么呢?是这样的 $#e#f#b#a#e#a#b#f#d# 此时很明显,p[id-(i-id)] 和p[i]二者相等
由此:
p[i]=min(p[id*2-i],maxn-i);接下来还得考虑下面这种情况:
$#a#a#b#a#e#a#b#a#e#a#b#
很明显此时p[i]的回文是很长的,我们在考虑完上述情况时还得考虑有没有可能p[i]是很大的并且大于p[id-(i-id)];
由此:
while(s[i-p[i]]==s[i+p[i]])p[i]++;
最后记得更新id 和maxn,完整代码如下:
#include <stdio.h>#include <cstring>#include <algorithm>using namespace std;#define MAX 100000char s[MAX*3];int p[MAX*3];int manacher(){ int ans=0,id=0,maxn=0,len=strlen(s); for(int i=len;i>=0;i--){ s[i*2+2]=s[i]; s[i*2+1]='#'; } s[0]='*'; for(int i=1;i<=len*2+1;i++){ if(maxn>i)p[i]=min(p[id*2-i],maxn-i); else p[i]=1; while(s[i-p[i]]==s[i+p[i]])p[i]++; if(ans<p[i])ans=p[i]; if(maxn<p[i]+i){ maxn=p[i]+i; id=i; } } /*printf("%s\n ",s); for(int i=1;i<=len*2+1;i++)printf("%d",p[i]);*/ return ans-1;}int main(){ memset(s,0,sizeof(s)); memset(p,0,sizeof(p)); scanf("%s",s); int ans=manacher(); printf("%d\n",ans);}
- Manacher算法
- Manacher算法
- Manacher算法
- Manacher算法
- Manacher 算法
- manacher算法
- manacher 算法
- Manacher算法
- manacher算法
- manacher算法
- manacher算法
- Manacher 算法
- Manacher算法
- manacher算法
- Manacher算法
- manacher算法
- Manacher算法
- Manacher算法:
- JAVA学习之类和对象
- 算法学习 2
- Chrome安装ARC Welder
- 线程与异常
- POJ 1703 Find them, Catch them 笔记
- manacher算法
- pat甲1020. Tree Traversals(已知后序和中序求层次遍历)
- 高仿微信5.2.1主界面及消息提醒
- Android这交互炸了:饿了么是怎么让Image变成详情页的
- vue.js 开发环境搭建最简单攻略
- 【kuangbin带你飞】之搜索 poj3278
- golang中使用package json遇到的问题
- 2016.12.03【初中部 NOIP提高C组】模拟赛题解
- kernel rpm包的制作