很好的总结,转自:

http://blog.csdn.net/dyx404514/article/details/42061017

总结为:两大情况,三小情况。

两大情况:I. i <= p

1.要处理的位置i及i为中心的回文半径Len[i] < p-i已经完全包含在某个回文中了,这种情况不用计算,len[i] = len[j]。

2.要处理的位置i在某个回文中,但是以i为中心的回文半径len[i] >= p-i,需要往后匹配,重新更新p,及对应的po和Len[i];

II. i > p

要计算的位置已经超出某个回文了,之前的回文已经没用,要重新计算新的位置了。只能挨个匹配了。

 // manacher.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
using namespace std; string ManaStr(string &orgStr,int length)
{//构造“马拉车”串
if(length == )
return NULL; string manacherString(*length+,'#');
for(int i = ;i < length;i++)
manacherString[*i+] = orgStr[i]; cout<<manacherString<<endl;
return manacherString;
} int manacher(string &manStr,int manacherLen)
{//“马拉车”计算过程,主要是每个位置对应的回文半径数组的生成,pArr[i]
if(manacherLen == )
return ; int Len[];//回文半径数组
for(int i = ; i <;i++)
Len[i] = ;
for(int i = ; i <;i++)
cout<<Len[i];
int po = ;//某个回文中心
int mostRight = -;//某个回文串最右的位置,并不包含这个位置
int result = ; //for(int i = 0;i != manacherLen;i++)
for(int i = ;i != ;i++)
{
Len[i] = mostRight > i ? min(mostRight-i,Len[*po-i]):;
/*
当前位置i包含在某个回文串中,那么Len[i]的值就是i到mostRight或者
关于po对称的j位置的Len值(j = 2*po-i)
*/
while(i+Len[i] < manacherLen && i-Len[i] >=)
{
if(manStr[i - Len[i]] == manStr[i + Len[i]])
Len[i]++;//检查是否可扩
else
break;
}
if(i+Len[i] > mostRight)
{//扩到mostRight之外了,旧的回文串就不起作用了,更新成新的回文串
//mostRight = Len[i] + 1;!!!!!!艹!!!会死人啊
mostRight = Len[i] + i;
po = i;
}
result = max(result,Len[i]);
}
return result - ;
} int _tmain(int argc, _TCHAR* argv[])
{
string originalString = "abc1234321ab";//结果应该为7
int originalLen = originalString.length();
//int originalLen = 12;
cout<<originalString<<endl;
string manacherString = ManaStr(originalString,originalLen);
int manStrLen = *originalLen + ;
cout<<"原串中包含的最长回文长度为:"<<manacher(manacherString,manStrLen)<<endl;
system("pause");
return ;
}

manacher

一个变形题

 // manacher_.cpp : 定义控制台应用程序的入口点。
//题目:给定一个串,求 在串的后边添加最小字符使得整体都是回文
//解法:利用manacher算法,当mostRight == length的时候停止,并记录下Len[i]
// 找到包含最后一个字符的回文串,之前的逆序就是要求的结果
//例子:abcd123321,在后边加dcba就是回文,返回dcba。 #include "stdafx.h"
#include <iostream>
#include <string>
using namespace std; string manStr(string &orgStr,int orgLen)
{
if(orgLen == )
return NULL; string manaString(*orgLen+,'#');
//string的一种构造方法string(num,ele)
for(int i = ; i < orgLen; i++)
manaString[*i+] = orgStr[i]; cout<<manaString<<endl;
return manaString;
} void manacherCore(string& mancherStr,int manaLen)
{
if(manaLen == )
return; int mostEnd = ;
int mostRight = -;
int po = ;
int Len[];
for(int i = ; i< ; i++)
Len[i] = ;//初始化Len for(int i = ;i != manaLen; i++)
{
Len[i] = mostRight > i? min(mostRight - i,Len[*po-i]):;
//while(i+Len[i] < manaLen && i- manaLen > -1)麻痹又写错
while(i+Len[i] < manaLen && i- Len[i] > -)
{
if(mancherStr[i + Len[i]] == mancherStr[i - Len[i]])
Len[i]++;
else
break;
}
if(i + Len[i] > mostRight)
{
mostRight =i + Len[i];
po = i;
}
if(mostRight == manaLen)
{
mostEnd = Len[i];
break;
}
}
//string result(10-(mostEnd-1),'0');//保存结果的string
string result(-mostEnd+,'');//这里应该是原串长度10
int resLen = result.length(); for (int i = ; i < resLen; i++)
result[resLen-i-] = mancherStr[*i+];
cout<<result<<endl; } int _tmain(int argc, _TCHAR* argv[])
{
string orginalStr = "abcd123321";
cout<<orginalStr<<endl;
int orgLen = orginalStr.length();
string mancherStr = manStr(orginalStr,orgLen);
int manaLen = mancherStr.length();
manacherCore(mancherStr,manaLen);
system("pause");
return ;
}

manacher变形

manacher算法_求最长回文子串长度的更多相关文章

  1. manacher算法学习(求最长回文子串长度)

    Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...

  2. Manacher模板( 线性求最长回文子串 )

    模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...

  3. Manacher算法讲解——字符串最长回文子串

    引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...

  4. 【Manacher算法】求最长回文串的优秀算法

    先贴一下代码~ //by 减维 #include<cstdio> #include<iostream> #include<cstring> #include< ...

  5. [hdu 3068] Manacher算法O(n)最长回文子串

    一个不错的讲解:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.05.md # ...

  6. Manacher 求最长回文子串算法

    Manacher算法,是由一个叫Manacher的人在1975年发明的,可以在$O(n)$的时间复杂度里求出一个字符串中的最长回文子串. 例如这两个回文串“level”.“noon”,Manacher ...

  7. Manacher算法(马拉车)求最长回文子串

    Manacher算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...

  8. Manacher算法:求解最长回文字符串,时间复杂度为O(N)

    原文转载自:http://blog.csdn.net/yzl_rex/article/details/7908259 回文串定义:"回文串"是一个正读和反读都一样的字符串,比如&q ...

  9. Manacher (马拉车) 算法:解决最长回文子串的利器

    最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...

随机推荐

  1. USACO Section 2.2: Party Lamps

    这题有个小技巧, 按一个键两次等于没按,所以如果depsum > 16的话其实不用做深搜到depsum次,而只要16次就可以了. /* ID: yingzho1 LANG: C++ TASK: ...

  2. php多维数组化一维数组

    一.使用foreach <?php function arr_foreach ($arr) { static $tmp=array(); if (!is_array ($arr)) { retu ...

  3. Android 获取最近应用的缩略图

    最近有项需求是获取应用的缩略,用于在动画时显示.因此就对此块知识简要了解了一下. 在android中获取视频文件的缩略图有三种方法: 1.从媒体库中查询 新视频增加后需要SDCard重新扫描才能给新增 ...

  4. CF 2013-2014CTS01E04(Killer Challenge-将质因数存在 进行Bitmask)

    首先,把P进行质因数分解,每一个不用的质因数压成1位 f[i][j]表示1前i位用j“拥有”的质因数表示. 然后都懂得... #include<cstdio> #include<cs ...

  5. Python3 学习第十二弹: 补充something

    python中遇到 *keys, **keys的形式 其实 * 代表传递任意个无名字参数,这些参数通过Tuple访问 >>> def sum(*keys): ret= 0 for i ...

  6. JS 去除字符串中的空格

    1. 去掉字符串前后所有空格: 代码如下: function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } 说明: ...

  7. checkbox美化;给div加上checked属性

    DIV的背景图修改 $("#isOpenmibao").css("backgroundImage", " url('../images/checkbo ...

  8. XmlElement可以避免由XmlSerializer多余生成的代码

    public class Program { static void Main(string[] args) { var alarm = new Alarm() { Code = "1588 ...

  9. NHibernate实例化类部分属性

    NHibernate 为习惯SQL的开发者提供了接口,将查询的结果转变为持久化对象.虽然该方法不是很提倡. GetCurrentSession().CreateSQLQuery(sql) 参数sql就 ...

  10. [转载] FFmpeg API 变更记录

    最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...