manacher算法_求最长回文子串长度
很好的总结,转自:
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算法_求最长回文子串长度的更多相关文章
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- Manacher算法讲解——字符串最长回文子串
引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...
- 【Manacher算法】求最长回文串的优秀算法
先贴一下代码~ //by 减维 #include<cstdio> #include<iostream> #include<cstring> #include< ...
- [hdu 3068] Manacher算法O(n)最长回文子串
一个不错的讲解:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.05.md # ...
- Manacher 求最长回文子串算法
Manacher算法,是由一个叫Manacher的人在1975年发明的,可以在$O(n)$的时间复杂度里求出一个字符串中的最长回文子串. 例如这两个回文串“level”.“noon”,Manacher ...
- Manacher算法(马拉车)求最长回文子串
Manacher算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...
- Manacher算法:求解最长回文字符串,时间复杂度为O(N)
原文转载自:http://blog.csdn.net/yzl_rex/article/details/7908259 回文串定义:"回文串"是一个正读和反读都一样的字符串,比如&q ...
- Manacher (马拉车) 算法:解决最长回文子串的利器
最长回文子串 回文串就是原串和反转字符串相同的字符串.比如 aba,acca.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
随机推荐
- USACO Section 2.2: Party Lamps
这题有个小技巧, 按一个键两次等于没按,所以如果depsum > 16的话其实不用做深搜到depsum次,而只要16次就可以了. /* ID: yingzho1 LANG: C++ TASK: ...
- php多维数组化一维数组
一.使用foreach <?php function arr_foreach ($arr) { static $tmp=array(); if (!is_array ($arr)) { retu ...
- Android 获取最近应用的缩略图
最近有项需求是获取应用的缩略,用于在动画时显示.因此就对此块知识简要了解了一下. 在android中获取视频文件的缩略图有三种方法: 1.从媒体库中查询 新视频增加后需要SDCard重新扫描才能给新增 ...
- CF 2013-2014CTS01E04(Killer Challenge-将质因数存在 进行Bitmask)
首先,把P进行质因数分解,每一个不用的质因数压成1位 f[i][j]表示1前i位用j“拥有”的质因数表示. 然后都懂得... #include<cstdio> #include<cs ...
- Python3 学习第十二弹: 补充something
python中遇到 *keys, **keys的形式 其实 * 代表传递任意个无名字参数,这些参数通过Tuple访问 >>> def sum(*keys): ret= 0 for i ...
- JS 去除字符串中的空格
1. 去掉字符串前后所有空格: 代码如下: function Trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } 说明: ...
- checkbox美化;给div加上checked属性
DIV的背景图修改 $("#isOpenmibao").css("backgroundImage", " url('../images/checkbo ...
- XmlElement可以避免由XmlSerializer多余生成的代码
public class Program { static void Main(string[] args) { var alarm = new Alarm() { Code = "1588 ...
- NHibernate实例化类部分属性
NHibernate 为习惯SQL的开发者提供了接口,将查询的结果转变为持久化对象.虽然该方法不是很提倡. GetCurrentSession().CreateSQLQuery(sql) 参数sql就 ...
- [转载] FFmpeg API 变更记录
最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...