什么是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. HTTP请求错误码大全(转)

    一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 详细分解: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明 ...

  2. POJ1259 The Picnic 最大空凸包问题 DP

    POJ1259 给定平面上100个点 求一个最大的凸包,使得它不包含其中任意点,且凸包的顶点是题目所给的点. 枚举凸包左下角的点,顺时针枚举第二个点, 用opt[i][j]记录 i作为第二个点, 且第 ...

  3. EasyUI 取得选中行数据

    转自:http://www.jeasyui.net/tutorial/23.html 本实例演示如何取得选中行数据. 数据网格(datagrid)组件包含两种方法来检索选中行数据: getSelect ...

  4. CodeForces 515C Drazil and Factorial (水题)

    题意:给出含有 n 个只有阿拉伯数字的字符串a,设定函数F(a) = 每个数字的阶乘乘积 .需要找出 x,使得F(x) = F(a),且组成 x 的数字中没有0和1.求最大的 x 为多少. 析:最大, ...

  5. bzoj 1827: [Usaco2010 Mar]gather 奶牛大集会【树形dp】

    不能用read会TLE!!不能用read会TLE!!不能用read会TLE!! 一开始以为要维护每个点,线段树写了好长(还T了-- 首先dfs一遍,求出点1为集会地点的答案,处理处val[u]为以1为 ...

  6. O(1)的快速乘

    那么 有位神仙已经说了O(1)的算法(当然不是我) 这是一种骚操作 直接放代码了啊 inline LL mul(LL a,LL b,LL Mod){ LL lf = a * ( b >> ...

  7. http2及server push

      本文主要研究下java9+springboot2+undertow2启用http2及server push maven <parent> <groupId>org.spri ...

  8. 模拟 HDOJ 5387 Clock

    题目传送门 /* 模拟:这题没啥好说的,把指针转成角度处理就行了,有两个注意点:结果化简且在0~180内:小时13点以后和1以后是一样的(24小时) 模拟题伤不起!计算公式在代码内(格式:hh/120 ...

  9. lua_protobuf

    http://www.cocoachina.com/bbs/read.php?tid-227404.html

  10. poi导出word时设置兼容性

    接上一篇poi导出word http://www.cnblogs.com/xiufengd/p/4708680.html. public static void setAuto(XWPFDocumen ...