ACM -- 算法小结(八)字符串算法之Manacher算法
- 字符串算法 -- Manacher算法
首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅。
//首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长。
//这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文有多长,
//这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。
//这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是
//充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。
//算法大致过程是这样。先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。
//一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了
//(见下面的一个例子,回文串长度全为奇数了),然后用一个辅助数组P记录以每个字符为中心的最长回文串的信息。
//P[id]记录的是以字符str[id]为中心的最长回文串,当以str[id]为第一个字符,这个最长回文串向右延伸了P[id]个字符。
// 原串: w aa bwsw f d
// 新串: # w # a # a # b # w # s # w # f # d #
//辅助数组P 1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
// 这里有一个很好的性质,P[id]-1就是该回文子串在原串中的长度(包括‘#’)。如果这里不是特别清楚,
//可以自己拿出纸来画一画,自己体会体会。当然这里可能每个人写法不尽相同,不过我想大致思路应该是一样的吧。
// 好,我们继续。现在的关键问题就在于怎么在O(n)时间复杂度内求出P数组了。只要把这个P数组求出来,最长回文子串就可以直接扫一遍得出来了。
// 由于这个算法是线性从前往后扫的。那么当我们准备求P[i]的时候,i以前的P[j]我们是已经得到了的。
//我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。
//(注:为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的)
//好,到这里,我们可以先贴一份代码了。
核心代码如下:
void pk()
{
int i;
int mx = ;
int id;
for(i=; i<n; i++)
{
if( mx > i )
p[i] = MIN( p[*id-i], mx-i );
else
p[i] = ;
for(; str[i+p[i]] == str[i-p[i]]; p[i]++) ;
if( p[i] + i > mx )
{
mx = p[i] + i;
id = i;
}
}
}
接下来到了小试牛刀的时刻啦~~ poj 3974 ,hdoj3068
#include<iostream>
#include<cstring>
using namespace std; const int N=;; char s1[N];
char s[N*];
int p[N*];
int n; int min(int a,int b)
{
if(a>b)
return b;
else
return a;
} int max(int a,int b)
{
if(a>b)
return a;
else
return b;
} void Manacher()
{
int i;
int mx=;
int id;
for(i=;i<n;i++)
{
if(mx>i)
p[i]=min(p[*id-i],mx-i);
else
p[i]=;
for( ;s[i+p[i]]==s[i-p[i]];p[i]++);
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
} int main()
{
int count=;
while(scanf("%s",s1)!=EOF,strcmp(s1,"END"))
{
int ans=;
int len=strlen(s1);
n=len*;
s[]='$';
// s[1]='#';
for(int i=;i<=len;i++)
{
s[*i+]='#';
s[*i+]=s1[i];
}
memset(p,,sizeof(p));
Manacher();
for(i=;i<n;i++)
ans=max(ans,p[i]);
printf("Case %d: %d\n",count++,ans-);
}
return ;
}
ACM -- 算法小结(八)字符串算法之Manacher算法的更多相关文章
- hdu3068 求一个字符串中最长回文字符串的长度 Manacher算法
最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 字符串-回文-Manacher算法
http://blog.csdn.net/zzkksunboy/article/details/72600679 https://segmentfault.com/a/1190000008484167 ...
- 计算字符串的最长回文子串 :Manacher算法介绍
转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...
- 【字符串】manacher算法
Definition 定义一个回文串为从字符串两侧向中心扫描时,左右指针指向得字符始终相同的字符串. 使用manacher算法可以在线性时间内求解出一个字符串的最长回文子串. Solution 考虑回 ...
- Manacher算法求解回文字符串
Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...
- 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树
另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...
- [转] Manacher算法详解
转载自: http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串 ...
- 最长回文子串问题-Manacher算法
转:http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串相算法 ...
- 【洛谷4287】[SHOI2011] 双倍回文(Manacher算法经典题)
点此看题面 大致题意: 求一个字符串中有多少个长度为偶数的回文串,它的一半也是回文串. \(Manacher\)算法 这应该是\(Manacher\)算法一道比较好的入门题,强烈建议在做这题之前先去学 ...
- 【BZOJ2565】最长双回文串 (Manacher算法)
题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...
随机推荐
- RMQ之ST求区间最大值
题目链接:https://cn.vjudge.net/problem/HRBUST-1188 每一次按照二进制的方式进行更新,二维数组dp [i] [j],i表示下标,j表示从i 开始的往后移动2的j ...
- docker 加速
Docker配置阿里云加速地址 打开阿里云网站https://cr.console.aliyun.com,登陆自己的阿里云账号. 然后只需要在服务器配置docker配置文件,只需要修改"Ex ...
- 导航狗IT周报-2018年05月27日
原文链接:https://www.daohanggou.cn/2018/05/27/it-weekly-9/ 摘要: “灰袍技能圈子”将闭圈:物理安全:为什么我们现在的生活节奏越来越快? 技术干货 1 ...
- 商城项目(ssm+dubbo+nginx+mysql统合项目)总结(1)
我不会在这里贴代码和详细步骤什么的,我觉得就算我把它贴出来,你们照着步骤做还是会出很多问题,我推荐你们去看一下黑马的这个视频,我个人感觉很不错,一步一步走下来可以学到很多东西.另外,视频和相关文档的话 ...
- device tree --- #address-cells and #size-cells property
device tree source Example1 / { #address-cells = <0x1>; // 在 root node 下使用 1 個 u32 來代表 address ...
- MGR Switch Muti-Primary to single_primary
MGR Muti-Primary 切换 single_primary 模式 原因:因为希望做ProxySQL+MGR之间Proxy层的消耗测试,需要把原有的MGR多主改为单主模式. 修改MGRgrou ...
- 细说show slave status参数详解(最全)【转】
在搭建好mysql主从之后,我们一般在从库上通过命令 show slave status\G 来查看主从的状态,会有很多的参数,接下来笔者就带大家好好的了解这些参数 root@localhost (n ...
- Codeforces Round #434 (Div. 2)
Codeforces Round #434 (Div. 2) 刚好时间对得上,就去打了一场cf,发现自己的代码正确度有待提高. A. k-rounding 题目描述:给定两个整数\(n, k\),求一 ...
- VC RichEdit中英文关键字标红
最近需要做vc的RichEdit控件里的内容关键字标红,由于RichEdit的内容可能是中英文混合的,所以需要先转成Unicode,再用wcsstr函数找到关键字出现的位置,再用SetSel.SelS ...
- C语言实现knn
以后写代码一定要谨慎,提高代码的正确率. /*************************************** * 1.初始化距离为最大值 * 2.计算未知样本和每个训练样本的距离为dis ...