manacher算法求最长回文串长度
2015-05-31 17:56
246 查看
manacher算法:
定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长
将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]?
由于s是从前扫到后的,所以需要计算p[i]时一定已经计算好了p[1]....p[i-1]
假设现在扫描到了i+k这个位置,现在需要计算p[i+k]
定义maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i]+i表示最大的
分两种情况:
1.i+k这个位置不在前面的任何回文串中,即i+k>maxlen,则初始化p[i+k]=1;//本身是回文串
然后p[i+k]左右延伸,即while(s[i+k+p[i+k]] == s[i+k-p[i+k]])++p[i+k]
2.i+k这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k
这样的话p[i+k]就不是从1开始
由于回文串的性质,可知i+k这个位置关于i与i-k对称,
所以p[i+k]分为以下3种情况得出
//黑色是i的回文串范围,蓝色是i-k的回文串范围,
manacher算法例题hdu-3068
定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长
将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i]就是最长回文串长度,则问题是如何去求p[i]?
由于s是从前扫到后的,所以需要计算p[i]时一定已经计算好了p[1]....p[i-1]
假设现在扫描到了i+k这个位置,现在需要计算p[i+k]
定义maxlen是i+k位置前所有回文串中能延伸到的最右端的位置,即maxlen=p[i]+i;//p[i]+i表示最大的
分两种情况:
1.i+k这个位置不在前面的任何回文串中,即i+k>maxlen,则初始化p[i+k]=1;//本身是回文串
然后p[i+k]左右延伸,即while(s[i+k+p[i+k]] == s[i+k-p[i+k]])++p[i+k]
2.i+k这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k
这样的话p[i+k]就不是从1开始
由于回文串的性质,可知i+k这个位置关于i与i-k对称,
所以p[i+k]分为以下3种情况得出
//黑色是i的回文串范围,蓝色是i-k的回文串范围,
manacher算法例题hdu-3068
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<stdlib.h> #include<iostream> #include<cctype> #include<vector> using namespace std; #define maxn 110010 char s[maxn*2]; int p[maxn*2]; int manacher(char s[]) { int len=strlen(s); int id=0,maxlen=0; for(int i=len;i>=0;i--) { s[i+i+2]=s[i]; //插入了len+1个'#',最终的s长度是2*len+1, s[i+i+1]='#'; } //首尾s[0]和s[2*len+2]要插入不同的字符 s[0]='@'; //s[0]='@',s[len+len+2]='\0',防止在while时p[i]越界 for(int i=2;i<2*len+1;i++) { if(p[id] + id > i) p[i] = min (p[2 * id - i],p[id] + id -i ); else p[i] = 1; while(s[i-p[i]] == s[i+p[i]]) p[i]++; if(id + p[id] < i + p[i]) id=i; if(maxlen < p[i]) maxlen = p[i]; } return maxlen - 1; } int main() { while(scanf("%s",s)!=EOF) { printf("%d\n",manacher(s)); } return 0; }
相关文章推荐
- NYOJ 6 喷水装置(一)
- G.711编解码原理
- AspNet MVC4 教学-21:Asp.Net MVC4 使用Ajax技术获取服务器时间快速Demo
- Activity-生命周期
- 用递归的思想写杨辉三角程序
- 实践
- jquer兄弟节点问题(购物评价星星)
- jquer多条件选择
- c++基础学习(03PM)
- 网络数据请求实践二:多文件上传的实现方法
- iOS开发笔记3:XML/JSON数据解析
- 远程SSH登陆方式备份和导入IOS系统和配置文件
- 线程同步 资源锁定(三)Event_CoundownEvent
- yum源的超级简单配置
- Vim/Vi基础
- android基础之Handler的使用(一)
- Dapper full example
- Hbase导入MapReduce数据的时候提示Running Job XXXX后就一直卡着不动
- 高级编程语言的发展历程(机器语言、汇编语言、高级语言)
- 第13周上机实践项目3——立体类族共有的抽象类