回文子串算法——Manacher学习
2016-04-13 19:47
183 查看
首次学习manacher算法,感谢分享优秀博文的博主:
http://blog.csdn.net/xingyeyongheng/article/details/9310555
读完后,我对其有了大体的认识。
经过manacher算法处理后的字符串,其内容完全改变。比如字符串212:
设p[i]是i位置处向外拓展的半径。
after the change, it’s
manacher算法的核心代码:
(下面代码主要用于说明)
接下来献上三道基础题:
求出串中回文子串的最大长度。
分析:manacher最简单的应用。
大意:先将整个字符串转化成原本的串(由给出的密码字符确定),然后由manacher算法求出最长的回文字符串,要求输出起点,终点,内容。
大意:求出完美串——回文子串,且满足H[1] <= H[2] <= H[3] …. <= H[mid] 山峰。
分析:中间过程处理一下,根据manacher算法得到的字符串的特点来更新山峰回文序列。
http://blog.csdn.net/xingyeyongheng/article/details/9310555
读完后,我对其有了大体的认识。
经过manacher算法处理后的字符串,其内容完全改变。比如字符串212:
设p[i]是i位置处向外拓展的半径。
after the change, it’s
type | contents |
---|---|
changed string | *#2#1#2#0 |
index (i) | 012345678 |
p[i] | 0021412 |
(下面代码主要用于说明)
int manacher(char *s, int p[]){ memset(p,0,sizeof(p)); int len=strlen(s); for(int i=len;i>=0;i--){ s[i+i+2]=s[i]; s[i+i+1]='#'; } s[0]='*'; len<<=1; len++; int l=0,maxn=0; for(int i=2;i<len;i++){ if(p[l]+l>i) p[i]=min(p[l]+l-i,p[2*l-i]); else p[i]=1; while(s[i-p[i]]==s[i+p[i]]) p[i]++; if(l+p[l]<i+p[i]) l=i; if(maxn<p[i]) maxn=p[i]; } return maxn-1; }
接下来献上三道基础题:
POj 3974 Palindrome
http://poj.org/problem?id=3974求出串中回文子串的最大长度。
分析:manacher最简单的应用。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=1e6+10; char s[2*N+10]; int p[2*N+10]; int main(int argc, char *argv[]) { int ca=1; while(~scanf("%s",s)){ if(strcmp(s,"END")==0) break; memset(p,0,sizeof(p)); int len=strlen(s); for(int i=len;i>=0;i--){ s[i+i+2]=s[i]; s[i+i+1]='#'; } s[0]='*'; len<<=1; len++; int l=0,maxn=0; for(int i=2;i<len;i++){ if(p[l]+l>i) p[i]=min(p[l]+l-i,p[2*l-i]); else p[i]=1; while(s[i-p[i]]==s[i+p[i]]) p[i]++; if(l+p[l]<i+p[i]) l=i; if(maxn<p[i]) maxn=p[i]; } printf("Case %d: %d\n",ca++,maxn-1); } return 0; }
hdu 3294 Girls’ research
http://acm.hdu.edu.cn/showproblem.php?pid=3294大意:先将整个字符串转化成原本的串(由给出的密码字符确定),然后由manacher算法求出最长的回文字符串,要求输出起点,终点,内容。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=2e5+10,M=2*N+10; char s[M],key; int p[M]; int main() { //freopen("cin.txt","r",stdin); int ca=1; while(~scanf("%c%s",&key,s)){ getchar(); int d=key-'a'; for(int i=0;s[i];i++) { s[i]-='a'; s[i]=(s[i]-d+26)%26; s[i]+='a'; //cout<<s[i]; } memset(p,0,sizeof(p)); int len=strlen(s); for(int i=len;i>=0;i--){ s[i+i+2]=s[i]; s[i+i+1]='#'; } s[0]='*'; len<<=1; len++; int l=0,maxn=0,ld=0,rd=0; for(int i=2;i<len;i++){ int tl=0,tr=0; if(p[l]+l>i) p[i]=min(p[l]+l-i,p[2*l-i]); else p[i]=1; while(s[i-p[i]]==s[i+p[i]]) { tl=i-p[i]; tr=i+p[i]; p[i]++; } if(l+p[l]<p[i]+i) l=i; if(maxn<p[i]) { maxn=p[i]; ld=tl; rd=tr; } } if(maxn-1>=2){ while(s[ld]<97||s[ld]>122) ld++; while(s[rd]<97||s[rd]>122) rd--; printf("%d %d\n",ld/2-1,rd/2-1); for(int i=ld;i<=rd;i++) if(s[i]<=122&&s[i]>=97) printf("%c",s[i]); puts(""); } else puts("No solution!"); } return 0; }
hdu 4513 吉哥系列故事――完美队形II
http://acm.hdu.edu.cn/showproblem.php?pid=4513大意:求出完美串——回文子串,且满足H[1] <= H[2] <= H[3] …. <= H[mid] 山峰。
分析:中间过程处理一下,根据manacher算法得到的字符串的特点来更新山峰回文序列。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=1e5+10; int s[2*N+10]; int p[2*N+10]; int main() { //freopen("cin.txt","r",stdin); int t,n; cin>>t; while(t--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&s[i]); memset(p,0,sizeof(p)); int len=n; for(int i=len;i>=0;i--){ s[i+i+2]=s[i]; s[i+i+1]=1; } s[0]=1000; len<<=1; len++; s[len+1]=1001; int l=0,maxn=0; for(int i=2;i<len;i++){ if(p[l]+l>i) p[i]=min(p[l]+l-i,p[2*l-i]); else p[i]=1; int tt=s[i]; if(tt<50){ if(s[i-p[i]]==s[i+p[i]]) { tt=s[i+p[i]]; p[i]++; } else continue; } while(s[i+p[i]]<50) p[i]++; // very important while(s[i-p[i]]==s[i+p[i]] && s[i+p[i]]<=tt) { tt=s[i+p[i]]; p[i]+=2; } if(p[l]+l<p[i]+i) l=i; if(maxn<p[i]) maxn=p[i]; } //for(int i=0;i<=len+2;i++) cout<<s[i]<<" "; cout<<endl; //for(int i=0;i<=len+2;i++) cout<<p[i]<<" "; cout<<endl; printf("%d\n",maxn-1); } return 0; }
相关文章推荐
- Run Qt5.6 on VS2015 & “无法迁移项目文件” & "Cannot instantiate QtProjectEngine object"错误的解决方法
- C语言-栈
- IL 常用指令
- gitlab集成redmine后,代码push的pre-receive脚本
- Android开源项目分类汇总
- 用pip安装
- Cannot find PHPUnit in include path phpstorm
- matlab神经网络工具箱创建神经网络
- srand((unsigned)(time(NULL)))的用法
- java开发之反射
- HDU-3081-Marriage Match II(最大流+并查集+二分)
- C语言-串
- poj1852Ants
- 360手机卫士---扫描杀雷达效果
- 第六周作业----内聚耦合
- python的基本输入输出
- leetcode——15——3Sum
- Windows 下的免费 SSH 客户端工具
- hibernate HQL语句
- bzoj 4448: [Scoi2015]情报传递