什么是Manacher算法?

转载自百度百科

Manachar算法主要是处理字符串中关于回文串的问题的,它可以在 O(n) 的时间处理出以字符串中每一个字符为中心的回文串半径,由于将原字符串处理成两倍长度的新串,在每两个字符之间加入一个特定的特殊字符,因此原本长度为偶数的回文串就成了以中间特殊字符为中心的奇数长度的回文串了。

Manacher算法提供了一种巧妙的办法,将长度为奇数的回文串和长度为偶数的回文串一起考虑,具体做法是,在原字符串的每个相邻两个字符中间插入一个分隔符,同时在首尾也要添加一个分隔符,分隔符的要求是不在原串中出现,一般情况下可以用#号。

一句话概括就是求解关于回文字串的一个线性方法

如何实现Manacher算法?

字符串改装函数trans

①使原字符串转换为奇数串

我们可以发现回文串有以下特征

①奇数串
②偶数串

其中不管奇数串还是偶数串只要每个字符后面加一个字符,再在开头加一个字符例如#会强制把他们都转换为奇数串例如bob->#b#o#b# dood->#d#o#o#d#并且他们的回文特性不变

并且可以发现一个规律那就是回文半径-1就是最大字串的回文长度,例如#b#o#b#的最大回文字串长度为4-1=3,#d#o#o#d#的最大回文长度为5-1=4

②确定回文起始位置的转换

我们还可以发现这样一个规律,如果开头再添加一个字符(应该为非#)例如$ bob->\(#b#o#b# dood->\)#d#o#o#d# 那么他的回文起始位置就在(原来带#的字符串的中心的数组下标-原来的回文半径)/2

例如$#b#o#b#的回文中心在(4-4)/2=0

$#d#o#o#d#=(5-5)/2=0

函数完整代码

string trans(string a)

{

string t="$#";//初始化开头

for(int i=0;i<a.size();i++)//每个后面加一个#

{

t+=a[i];

t+='#';

}

return t;//返回

}

回文半径数组p[i]的计算

完全是下面这一行的精髓

p[i] = mx > i ? min(p[2 * id - i], mx - i) : 1;

目前还对这一行并不是很理解无法说明,但是可以记住这是一个规律

完整代码(洛谷模板题 P3805 【模板】manacher算法)

#include <bits/stdc++.h>
using namespace std;
string trans(string a)
{
string t="$#";//初始化开头
for(int i=0;i<a.size();i++)//每个后面加一个#
{
t+=a[i];
t+='#';
}
return t;//返回
}
int p[110000050];//开大一点开小了还re
int main()
{
ios::sync_with_stdio(0);//关闭同步三步走
cin.tie(0);cout.tie(0);
string a,b;//输入原字符串
cin>>a;
b=a;
a=trans(a);//转换
int mx,id,rl,rc,ans=-1;
for(int i=1;i<a.size();i++)
{
p[i]=mx>i?min(p[2*id-i],mx-i):1;//求p[i]的初始值
while(a[i+p[i]]==a[i-p[i]])//如果回文半径延伸可以的话,p[i]++
p[i]++;
if(mx<i+p[i])//如果具有回文性质的最右边界小于目前更新的回文半径
{
mx=i+p[i];//更新右边界
id=i;//更新回文子串的初始位置
}
ans=max(ans,p[i]-1);//寻找最大值
}
cout<<ans;
/*输出回文子串
cout<<"\n";
for(int i=(id-ans)/2;i<ans;i++)
cout<<b[i];
cout<<"\n";*/
}

最新文章

  1. C++随笔:从Hello World 探秘CoreCLR的内部(1)
  2. 关于Unity的网络框架
  3. putty如何使用
  4. C++求最小公倍数
  5. 转:我们是否应该把后端构建为API
  6. Android 2014年1月22日
  7. NET Core RC2
  8. 日交易41.9亿,B2B的魅力为何不输于B2C、C2C?
  9. jquery控制图片切换
  10. javascript设计模式详解之命令模式
  11. BZOJ_[JSOI2010]Group 部落划分 Group_kruskal
  12. JAVA多线程-初体验
  13. 定时器修改button标题闪烁
  14. 设计模式《JAVA与模式》之备忘录模式
  15. 1. git基础
  16. 完爆Facebook/GraphQL,APIJSON全方位对比解析(三)-表关联查询
  17. jquery 回车事件实现代码
  18. FreeOpcUa compile
  19. ARKit-1
  20. asp.net core添加全局异常处理及log4net、Nlog应用

热门文章

  1. SpringMVC_2
  2. Silverlight之控件应用总结(二)(4)
  3. git 配置代理
  4. Ado.net设计模式
  5. 记录一次Mysql死锁排查过程
  6. bat 截取字符串(for命令) 推荐收藏
  7. Eclipse 安装 Maven 插件的几种方法
  8. 函数bsxfun,两个数组间元素逐个计算的二值操作
  9. sqlserver2000连接失败,不存在或拒绝访问
  10. va_start和va_end使用详解(转载)