Manacher算法(马拉车算法)浅谈
什么是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算法(马拉车算法)浅谈的更多相关文章
- 【字符串算法2】浅谈Manacher算法
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 字符串算法2:Manacher算法 问题:给出字符串S(限制见后)求出最 ...
- 【字符串算法3】浅谈KMP算法
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 [字符串算法3]KMP算法 Part1 理解KMP的精髓和思想 其实KM ...
- Manacher算法 (马拉车算法)
#include<iostream> #include<string.h> #include<algorithm> using namespace std; ]; ...
- 浅谈压缩感知(二十四):压缩感知重构算法之子空间追踪(SP)
主要内容: SP的算法流程 SP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 SP与CoSaMP的性能比较 一.SP的算法流程 压缩采样匹配追踪(CoSaMP)与子 ...
- 浅谈算法——Manacher
字符串算法在各大高级比赛中均有用到,所以,学习好字符串算法对我们而言十分重要.那么,今天我们就给大家介绍一个快速求回文串的算法,Manacher算法,我们也习惯性叫它马拉车算法. 一.引入 首先我们要 ...
- Manacher's Algorithm 马拉车算法
这个马拉车算法Manacher‘s Algorithm是用来查找一个字符串的最长回文子串的线性方法,由一个叫Manacher的人在1975年发明的,这个方法的最大贡献是在于将时间复杂度提升到了线性,这 ...
- 浅谈URLEncoder编码算法
一.为什么要用URLEncoder 客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文. 而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址, 将 ...
- 浅谈Hex编码算法
一.什么是Hex 将每一个字节表示的十六进制表示的内容,用字符串来显示. 二.作用 将不可见的,复杂的字节数组数据,转换为可显示的字符串数据 类似于Base64编码算法 区别:Base64将三个字节转 ...
- 浅谈Base64编码算法
一.什么是编码解码 编码:利用特定的算法,对原始内容进行处理,生成运算后的内容,形成另一种数据的表现形式,可以根据算法,再还原回来,这种操作称之为编码. 解码:利用编码使用的算法的逆运算,对经过编码的 ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
随机推荐
- YTU 2509: 奇怪的分式
2509: 奇怪的分式 时间限制: 1 Sec 内存限制: 128 MB 提交: 113 解决: 48 题目描述 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8 ...
- 【Codevs 1376】帕秋莉•诺蕾姬
http://codevs.cn/problem/1376/ 枚举修改哪两位,将sum减去之前位置的数+交换之后 %m==0即可 预处理26的次方+O(n^2) // <1376.cpp> ...
- 动态更改Menu
好像没有现成的api可能获取menu完美方法,只有在创建menu时,用全局的menuItem记下, 在需要修改时修改. 1)全局量: MenuItem gMenuItem=NULL; 2)//创建菜 ...
- luogu 3375 【模板】KMP字符串匹配
我太菜了 今天才学会kmp #include<iostream> #include<cstdio> #include<algorithm> #include< ...
- P3199 [HNOI2009]最小圈 01分数规划
裸题,第二个权值是自己点的个数.二分之后用spfa判负环就行了. 题目描述 考虑带权的有向图G=(V,E)G=(V,E)G=(V,E)以及w:E→Rw:E\rightarrow Rw:E→R,每条边e ...
- xargs 主要用于不支持管道的shell命令*****
变量置换,主要用于不支持管道的shell命令,如:rm.sed等,但有些命令需要占位符“{}”需要注意.比如:删除文件- ls|xargs -i rm -rf {} 文件改名- ls|xargs ...
- odb_sqlite_demo
#include <iostream> #include <odb/database.hxx> #include <odb/transaction.hxx ...
- bzoj1776
点分治/贪心 对于点分治的理解不够深刻...点分治能统计树上每个点对的信息,那么这里就是统计同种颜色点对之间的最大距离,自然可以用点分 然后点分,每次统计最大距离,但是略微卡常... 还有一种贪心的方 ...
- [转] 本地项目上传github (新项目 / 旧项目)
前置:安装Git Bash,在github上新建仓库repository 1.右键点击项目所在文件夹,运行: git bash here.在git bash窗口运行命令 git init 把这个目录变 ...
- Python print 输出不换行,只有空格
for x in open("/home/soyo/桌面/中期内容/6.txt"): print x, ,,,]: print x, #print 输出没有换行,只有空格 结果: ...