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.前一个是奇数长度的回文串,后一个是偶数长度的回文串. 最长回文子串就是一个字符串的所有子串中,是回文串且长度最长的子串. ...
随机推荐
- Line Search and Quasi-Newton Methods 线性搜索与拟牛顿法
Gradient Descent 机器学习中很多模型的参数估计都要用到优化算法,梯度下降是其中最简单也用得最多的优化算法之一.梯度下降(Gradient Descent)[3]也被称之为最快梯度(St ...
- mysql 转义字符和php addslashes
遇到一个很奇怪的问题,json数据中含有中文: "mail":{"title":"\u6218\u529b\u8fbe\u4eba\u6d3b\u52 ...
- javascript 递归调用
上源码:underscore.js var flatten = function(input, shallow, output) { if (shallow && _.every(in ...
- Git - Tutorial官方【转】
转自:http://www.vogella.com/tutorials/Git/article.html#git_rename_branch Lars Vogel Version 5.8 Copyri ...
- hihoCoder 1039字符消除 (字符串处理)
http://hihocoder.com/problemset/problem/1039 因为字符串只由3种字母组成,并且插入的字符也只能是这三种字符的其中一个,那么可以考虑枚举这三个字符其中一个字符 ...
- R语言iris数据集的层次聚类
data=iris[,-5]dist.e=dist(data,method='euclidean')model1=hclust(dist.e,method='ward') #分3类result=cut ...
- UVa 10954 (Huffman 优先队列) Add All
直接用一个优先队列去模拟Huffman树的建立过程. 每次取优先队列前两个数,然后累加其和,把这个和在放入到优先队列中去. #include <cstdio> #include <q ...
- UIImagePicker照片选择器
UIImagePickerController 1.+(BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType ...
- Cocoa & Cocoa Touch概念
Application Kit框架包括广泛的类和方法,它们用来开发交互式图形应用程序,使得开发文本/菜单/工具栏/表/文档/剪贴板和窗口之类的过程变得十分简便.在Mac OSX操作系统中,术语coco ...
- 封装sharedPreferences SettingsSPData
/*************************************************************************** * 封装sharedPreferences S ...