• 字符串算法 -- 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. Python ctypes中cast/py_object用法

    class ctypes.py_object Represents the C PyObject * datatype. Calling this without an argument create ...

  2. php简单文件管理器——php经典实例

    <html> <head> <title>文件管理</title> <meta charset='utf-8' /> </head&g ...

  3. 无key值的json数组解析

    [    [        {            "cartId": 9223,            "factoryId": 143,          ...

  4. bootstrap带图标的按钮与图标做连接

    bootstrap通过引入bootstrap的JS与css文件,给元素添加class属性即可. 使用图标只需要加入一个span,class属性设置为对应的图标属性即可.图标对应的class属性可以参考 ...

  5. JDK1.8新特性

    1.Lambda                                                            Lambda的语法目前仅对于只有一个抽象方法的接口. 在Lamb ...

  6. git命令大全【转】

    转自:http://www.jqhtml.com/8235.html 初始化本地git仓库(创建新仓库) git init 配置用户名 git config --global user.name &q ...

  7. linux下C语言实现的内存池【转】

    转自:http://blog.chinaunix.net/uid-28458801-id-4254501.html 操作系统:ubuntu10.04 前言:     在通信过程中,无法知道将会接收到的 ...

  8. Python 中的闭包与装饰器

    闭包(closure)是函数式编程的重要的语法结构.闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性. 如果在一个内嵌函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内嵌函数 ...

  9. centos6.5 使用 rpm 安装 mysql

    从mysql网站下载mysql rpm安装包(包括server.client) 1.安装server rpm -ivh MySQL-server-5.6.19-1.el6.x86_64.rpm 强制安 ...

  10. for循环练习题(共六道题)

    第一题: 假设一个简单的ATM机的取款过程是这样的:首先提示用户输入密码(password),最多只能输入三次,超过3次则提示用户“密码错误,请取卡”结束交易.如果用户密码正确,再提示用户输入取款金额 ...