博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
manacher浅析
阅读量:6341 次
发布时间:2019-06-22

本文共 913 字,大约阅读时间需要 3 分钟。

manacher算法的输入是一个字符串,可以计算出以每个字符为中心的最长回文子串的半径。为了避免讨论奇数偶数,将原串的每两个字母之间以及前后各加一个特殊字母,比如'#',那么对于abcbb就变成了 #a#b#c#b#b#,串的长度变成了11,我们用dp[i]表示以i为中心的最长回文的半径,那么上面的串的dp值如下:

# a # b # c # b # b #
1 2 1 2  1 4 1 2 3 2 1
设串为S,那么S[i-dp[i]+1,i-1]=S[i+1,i+dp[i]-1]。

我们从前向后依次计算每个位置的dp值。设现在计算到了i位置,之前所有位置j的最大的j+dp[j]的位置为id,Max=id+dp[id]。

下面分三种情况(设j=2*id-i,即j为i关于id的对称点):

(1)Max-i>dp[j]:如下图,这说明以j为中心的回文串完全在以id为中心的回文串的内部,那么由于对称性可得,以i为中心的回文串的半径dp[i]=dp[j]。

(2)Max-i<=dp[j]:如下图,那么以j为中心的回文串超出了以id为中心的回文串,那么绿色方框内的部分必然是对称的,那么dp[i]至少等于Max-i。外面的不能确定,我们可以强行匹配。

(3)Max<=i,我们强行匹配这种情况即可。

代码如下,为了方便,在最开始加入一个特殊字母'$'

1 void manacher(char *s,int n,char *S,int dp[]) 2 { 3     int cur=0; 4     S[cur++]='$'; 5     S[cur++]='#'; 6     for(int i=0;i
i?min(dp[2*id-i],Max-i):1;12 while(S[i+dp[i]]==S[i-dp[i]]) dp[i]++;13 if(i+dp[i]>Max) Max=i+dp[i],id=i;14 }15 }

 

转载于:https://www.cnblogs.com/jianglangcaijin/p/6035786.html

你可能感兴趣的文章
javascript面向对象2
查看>>
限制容器对CPU的使用 - 每天5分钟玩转 Docker 容器技术(28)
查看>>
jquery 实现的一个 随机云标签网页背景
查看>>
RPC
查看>>
android广播事件处理broadcast receive
查看>>
在eclipse 里面 修改tomcat的配置--Server Locations
查看>>
网站 mvc url 路径 设置 为 *.html 的原因
查看>>
mybatis 开启使用 默认的 二级缓存
查看>>
docker 容器 创建和 使用
查看>>
SQLITE使用指南
查看>>
我的友情链接
查看>>
Red Hat7版本本地仓库yum源的配置
查看>>
Linux学习-环境变量
查看>>
用Maven部署war包到远程Tomcat服务器
查看>>
android字体大小的设置
查看>>
2015.06.04 工作任务与心得
查看>>
icinga2使用587端口发邮件
查看>>
hpasmcli查看HP服务器内存状态
查看>>
极客工具
查看>>
【14】Python100例基础练习(1)
查看>>