什么是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";*/
}

Manacher算法(马拉车算法)浅谈的更多相关文章

  1. 【字符串算法2】浅谈Manacher算法

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  字符串算法2:Manacher算法 问题:给出字符串S(限制见后)求出最 ...

  2. 【字符串算法3】浅谈KMP算法

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法3]KMP算法 Part1 理解KMP的精髓和思想 其实KM ...

  3. Manacher算法 (马拉车算法)

    #include<iostream> #include<string.h> #include<algorithm> using namespace std; ]; ...

  4. 浅谈压缩感知(二十四):压缩感知重构算法之子空间追踪(SP)

    主要内容: SP的算法流程 SP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 SP与CoSaMP的性能比较 一.SP的算法流程 压缩采样匹配追踪(CoSaMP)与子 ...

  5. 浅谈算法——Manacher

    字符串算法在各大高级比赛中均有用到,所以,学习好字符串算法对我们而言十分重要.那么,今天我们就给大家介绍一个快速求回文串的算法,Manacher算法,我们也习惯性叫它马拉车算法. 一.引入 首先我们要 ...

  6. Manacher's Algorithm 马拉车算法

    这个马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...

  7. 浅谈URLEncoder编码算法

    一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...

  8. 浅谈Hex编码算法

    一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...

  9. 浅谈Base64编码算法

    一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...

  10. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

随机推荐

  1. YTU 2898: C-Z型变换

    2898: C-Z型变换 时间限制: 1 Sec  内存限制: 128 MB 提交: 53  解决: 15 题目描述 让我们来玩个Z型变换的游戏,游戏的规则如下: 给你一个字符串,将它以Z字型的形状不 ...

  2. POJ 1060:Modular multiplication of polynomials

    Modular multiplication of polynomials Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4 ...

  3. 8-2 canvas专题-线条样式

    8-2 canvas专题-线条样式 学习要点 对第五章知识进行简单的回顾和总结 进一步讲解canvas绘图相关的知识点 第八章内容介绍 在第八章中我们将对以前的知识进行简单的回顾,着重对canvas绘 ...

  4. 7-80 HTML5新增的JS选择器

    7-80 HTML5新增的JS选择器 学习要点 HTML5新增的JS选择器 在传统的 JavaScript 开发中,原生的 JavaScript 所提供的 DOM 选择方法并不多,仅仅局限于通过 ta ...

  5. 微信公众平台appid和appsecret在哪

    1.appid和appsecret是微信公众平台服务号才有的,如果自己家的公众平台不是服务号,需要升级为服务号. 2.登录服务号,登录“服务”条目,“服务中心”如图. 3.点击“自定义菜单”-“开发模 ...

  6. Google Closure Compiler 高级模式及更多思考(转)

    前言 Google Closure Compiler 是 Google Closure Tools 的一员,在 2009 年底被 Google 释出,早先,有 玉伯 的 Closure Compile ...

  7. AGC16E Poor Turkeys

    输入样例: 10 10 8 9 2 8 4 6 4 9 7 8 2 8 1 8 3 4 3 4 2 7 输出样例#6: 5 话说这题虽然不是很OI但是确实挺锻炼思维的 一开始以为是用并查集之类的东西维 ...

  8. SQL数据库——静态成员

    静态: 1.普通成员普通成员都是属于对象的用对象调用 2.静态成员静态成员是属于类的用类名调用 stactic 静态关键字 静态方法里面不能包含普通成员普通方法里面可以包含静态成员 静态: 1.普通成 ...

  9. Java使用 POI 操作Excel

    Java中常见的用来操作 Excel 的方式有2种:JXL和POI.JXL只能对 Excel进行操作,且只支持到 Excel 95-2000的版本.而POI是Apache 的开源项目,由Java编写的 ...

  10. git初使用的心得

    转到Java方向后,版本控制工具也开始以git为主了.由于之前不怎么使用bash,所以目前还是以ui工具,比如sourcetree为主导,但一些简单的操作命令,已经能够快速地使用.sourcetree ...