• 字符串算法 -- Manacher算法

首先介绍基础入门知识,以下这部分来着一贴吧,由于是很久之前看的,最近才整理一下,发现没有保存链接,请原创楼主见谅。

  1. //首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长。
  2. //这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文有多长,
  3. //这个算法有一个很巧妙的地方,它把奇数的回文串和偶数的回文串统一起来考虑了。
  4. //这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是
  5. //充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。
  6. //算法大致过程是这样。先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。
  7. //一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了
  8. //(见下面的一个例子,回文串长度全为奇数了),然后用一个辅助数组P记录以每个字符为中心的最长回文串的信息。
  9. //P[id]记录的是以字符str[id]为中心的最长回文串,当以str[id]为第一个字符,这个最长回文串向右延伸了P[id]个字符。
  10. // 原串: w aa bwsw f d
  11. // 新串: # w # a # a # b # w # s # w # f # d #
  12. //辅助数组P 1 2 1 2 3 2 1 2 1 2 1 4 1 2 1 2 1 2 1
  13. // 这里有一个很好的性质,P[id]-1就是该回文子串在原串中的长度(包括‘#’)。如果这里不是特别清楚,
  14. //可以自己拿出纸来画一画,自己体会体会。当然这里可能每个人写法不尽相同,不过我想大致思路应该是一样的吧。
  15. // 好,我们继续。现在的关键问题就在于怎么在O(n)时间复杂度内求出P数组了。只要把这个P数组求出来,最长回文子串就可以直接扫一遍得出来了。
  16. // 由于这个算法是线性从前往后扫的。那么当我们准备求P[i]的时候,i以前的P[j]我们是已经得到了的。
  17. //我们用mx记在i之前的回文串中,延伸至最右端的位置。同时用id这个变量记下取得这个最优mx时的id值。
  18. //(注:为了防止字符比较的时候越界,我在这个加了‘#’的字符串之前还加了另一个特殊字符‘$’,故我的新串下标是从1开始的)
  19. //好,到这里,我们可以先贴一份代码了。

核心代码如下:

  1. void pk()
  2. {
  3. int i;
  4. int mx = ;
  5. int id;
  6. for(i=; i<n; i++)
  7. {
  8. if( mx > i )
  9. p[i] = MIN( p[*id-i], mx-i );
  10. else
  11. p[i] = ;
  12. for(; str[i+p[i]] == str[i-p[i]]; p[i]++) ;
  13. if( p[i] + i > mx )
  14. {
  15. mx = p[i] + i;
  16. id = i;
  17. }
  18. }
  19. }

接下来到了小试牛刀的时刻啦~~ poj 3974 ,hdoj3068

  1. #include<iostream>
  2. #include<cstring>
  3. using namespace std;
  4.  
  5. const int N=;;
  6.  
  7. char s1[N];
  8. char s[N*];
  9. int p[N*];
  10. int n;
  11.  
  12. int min(int a,int b)
  13. {
  14. if(a>b)
  15. return b;
  16. else
  17. return a;
  18. }
  19.  
  20. int max(int a,int b)
  21. {
  22. if(a>b)
  23. return a;
  24. else
  25. return b;
  26. }
  27.  
  28. void Manacher()
  29. {
  30. int i;
  31. int mx=;
  32. int id;
  33. for(i=;i<n;i++)
  34. {
  35. if(mx>i)
  36. p[i]=min(p[*id-i],mx-i);
  37. else
  38. p[i]=;
  39. for( ;s[i+p[i]]==s[i-p[i]];p[i]++);
  40. if(p[i]+i>mx)
  41. {
  42. mx=p[i]+i;
  43. id=i;
  44. }
  45. }
  46. }
  47.  
  48. int main()
  49. {
  50. int count=;
  51. while(scanf("%s",s1)!=EOF,strcmp(s1,"END"))
  52. {
  53. int ans=;
  54. int len=strlen(s1);
  55. n=len*;
  56. s[]='$';
  57. // s[1]='#';
  58. for(int i=;i<=len;i++)
  59. {
  60. s[*i+]='#';
  61. s[*i+]=s1[i];
  62. }
  63. memset(p,,sizeof(p));
  64. Manacher();
  65. for(i=;i<n;i++)
  66. ans=max(ans,p[i]);
  67. printf("Case %d: %d\n",count++,ans-);
  68. }
  69. return ;
  70. }

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. IE9 下 ellipsis bug fix

    fiddle: http://jsfiddle.net/tagliala/TtbuG/10/ original: https://github.com/FortAwesome/Font-Awesome ...

  2. SSO单点登录的发展由来以及实现原理【转】

    单点登录以及权限,在很早之前都有写过,不过都比较简单,今天就具体说一下,以及下一步要做的 1.web单系统应用 早期我们开发web应用都是所有的包放在一起打成一个war包放入tomcat容器来运行的, ...

  3. Linux 上配置 NTP SERVER

    在CENTOS 6.2上面安装配置NTP SERVER 安装NTP:yum install ntp 配置时间源vi /etc/ntp.confserver 210.72.145.44server nt ...

  4. Ural Sport Programming Championship 2015

    Ural Sport Programming Championship 2015 A - The First Day at School 题目描述:给出课程安排,打印一个课程表. solution 暴 ...

  5. Linux Supervisor的安装与使用入门---SuSE

    Linux Supervisor的安装与使用入门 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事 ...

  6. Gradient-Based Learning Applied to Document Recognition 部分阅读

    卷积网络        卷积网络用三种结构来确保移位.尺度和旋转不变:局部感知野.权值共享和时间或空间降采样.典型的leNet-5如下图所示: C1中每个特征图的每个单元和输入的25个点相连,这个5* ...

  7. initialization 与 finalization 执行顺序 研究

    看GIF: 第二个GIF: DEMO下载:http://files.cnblogs.com/files/del88/InitOrderDemo.zip

  8. Gitlab部署及汉化操作

    一.简介 GitLab是一个利用 Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目. GitLab拥有与Github类似的功能 ...

  9. 三十分钟理解计算图上的微积分:Backpropagation,反向微分

    神经网络的训练算法,目前基本上是以Backpropagation (BP) 反向传播为主(加上一些变化),NN的训练是在1986年被提出,但实际上,BP 已经在不同领域中被重复发明了数十次了(参见 G ...

  10. 【转】servlet/filter/listener/interceptor区别与联系

    原文:https://www.cnblogs.com/doit8791/p/4209442.html 一.概念: 1.servlet:servlet是一种运行服务器端的java应用程序,具有独立于平台 ...