• 字符串算法 -- 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算法的更多相关文章

  1. hdu3068 求一个字符串中最长回文字符串的长度 Manacher算法

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  2. 字符串-回文-Manacher算法

    http://blog.csdn.net/zzkksunboy/article/details/72600679 https://segmentfault.com/a/1190000008484167 ...

  3. 计算字符串的最长回文子串 :Manacher算法介绍

    转自: http://www.open-open.com/lib/view/open1419150233417.html Manacher算法 在介绍算法之前,首先介绍一下什么是回文串,所谓回文串,简 ...

  4. 【字符串】manacher算法

    Definition 定义一个回文串为从字符串两侧向中心扫描时,左右指针指向得字符始终相同的字符串. 使用manacher算法可以在线性时间内求解出一个字符串的最长回文子串. Solution 考虑回 ...

  5. Manacher算法求解回文字符串

    Manacher算法可以在\(O(N)\)时间内求解出一个字符串的所有回文子串(正反遍历相同的字串). 注:回文串显然有两种,一种是奇数长度,如abczcba,有一个中心字符z:另外一种是偶数个长度, ...

  6. 【Todo】字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树

    另开一文分析字符串相关的各种算法,以及用到的各种数据结构,包括前缀树后缀树等各种树. 先来一个汇总, 算法: 本文中提到的字符串匹配算法有:KMP, BM, Horspool, Sunday, BF, ...

  7. [转] Manacher算法详解

    转载自: http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串 ...

  8. 最长回文子串问题-Manacher算法

    转:http://blog.csdn.net/dyx404514/article/details/42061017 Manacher算法 算法总结第三弹 manacher算法,前面讲了两个字符串相算法 ...

  9. 【洛谷4287】[SHOI2011] 双倍回文(Manacher算法经典题)

    点此看题面 大致题意: 求一个字符串中有多少个长度为偶数的回文串,它的一半也是回文串. \(Manacher\)算法 这应该是\(Manacher\)算法一道比较好的入门题,强烈建议在做这题之前先去学 ...

  10. 【BZOJ2565】最长双回文串 (Manacher算法)

    题目: BZOJ2565 分析: 首先看到回文串,肯定能想到Manacher算法.下文中字符串\(s\)是输入的字符串\(str\)在Manacher算法中添加了字符'#'后的字符串 (构造方式如下) ...

随机推荐

  1. JS设计模式——4.继承(概念)

    类式继承 0.构造函数 一个简单的Person类 function Person(name){ this.name = name; } Person.prototype.getName = funct ...

  2. Linux必备工具Tmux

    之前介绍了Linux的Screen命令,今天介绍一个更为强大的终端工具Tmux. Tmux 是一个用于在一个终端窗口中运行多个终端会话的工具.它基本能替代nohup以及screen,甚至比它们更为强大 ...

  3. Sqlmap注入技巧收集整理

    TIP1 当我们注射的时候,判断注入 http://site/script?id=10http://site/script?id=11-1 # 相当于 id=10http://site/script? ...

  4. VueJS 集成 medium editor 自定义编辑器按钮

    详见我的新博客: 守望之吻

  5. 【Python学习】request库

    Requests库(https://www.python-requests.org/)是一个擅长处理那些复杂的HTTP请求.cookie.header(响应头和请求头)等内容的Python第三方库. ...

  6. cpu几种架构区别

    转自:http://smilejay.com/2012/07/intel-procssor-architecture/ (1)x86 (IA-32,i386,x86-32,x32) x86是指基于In ...

  7. 非交互式shell脚本案例-实现自主从oracle数据库获取相关数据,并在制定目录生成相应规则的文件脚本

    get_task_id 脚本内容 #!/usr/bin/expect#配置登陆数据库的端口set port 22#配置登陆数据库的ip地址set oracleip 10.0.4.41#配置数据库实例名 ...

  8. python之pandas&&DataFrame(二)

    简单操作 Python-层次聚类-Hierarchical clustering >>> data = pd.Series(np.random.randn(10),index=[[' ...

  9. Regular Expression Matching——没理解的动态规划

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  10. web_reg_save_param_regexp函数的用法

    关联从服务器返回的所有的内容: 本例通过一个使用HTTP/HTML协议发送.获取服务器数据的vuser脚本,分析LoadRunner如何进行HTTP关联. 下面这个例子包括两个事务:上传数据到服务器. ...