什么是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. ORACLE分区表发挥性能

    1.1 分区表PARTITION table 在ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能. 1.1.1 分区表的建立: 某公司的每年产生巨大的销售记录,DBA向公司建议 ...

  2. python datatime日期和时间值模块

    datetime.time():是一个时间类,这个类接受4个参数,分别代表时,分,秒,毫秒.参数的默认值是为0 #!/usr/bin/env python #coding:utf8 import da ...

  3. GCD中各种队列和任务执行方式的组合

    一.概念回顾 1.GCD全称 Grand Central Dispatch ,是纯C语言,提供了非常多强大的函数,来进行系统线程的管理. 2.优势:GCD是苹果公司为多核的并行运算提出的解决方案.GC ...

  4. bzoj 1635: [Usaco2007 Jan]Tallest Cow 最高的牛【差分】

    s[i]为差分后的"i这头牛前有几头比它高",计算答案的时候加成前缀和,假设第一头最高减一下即可 用map记录一下被加过的区间,避免重复 #include<iostream& ...

  5. less新手入门(五)—— CssGuards、循环、合并

    九. CssGuards 警卫也可以应用于css选择器,这是一种语法糖,用于声明mixin,然后立即调用它. 例如,在1.5.0之前,您必须这样做 .my-optional-style() when ...

  6. eclipse mybatis 快速生成工具

    1.首先,得先看看eclipse有没安装mybatis generator插件,如果有的话,请忽略这一步 eclipse在线安装mybatis generator 1.打开eclipse,找到help ...

  7. [译]HTTP POSTing

    HTTP POSTing We get many questions regarding how to issue HTTP POSTs with libcurl the proper way. Th ...

  8. [转]Git使用基础篇

    http://www.git-scm.com/ https://try.github.io/levels/1/challenges/1 本文转自:http://www.open-open.com/li ...

  9. Dubbo和Zookeeper

    一.软件架构演进 ​ 软件架构的发展经历了由单体架构.垂直架构.分布式架构到流动计算架构的演进过程. 1.单一架构 ​ 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本.此 ...

  10. Spring-Aop的两种代理方式

    Spring-Aop两种代理方式: 1.JDK动态代理:用于目标类实现了接口: 2.Cglib动态代理:用于目标类没有实现接口: spring会依据目标类是否实现接口来选择使用哪种代理方式(目标类:相 ...