http://acm.hdu.edu.cn/showproblem.php?pid=3068
今天看了一道关于求最长回文子串的题目,题意非常容易理解,题目也比较简单,就是感觉数据量非常的大,没有敢用暴力的方法进行匹配。
最后搜了一下网上的方法,大家有些用扩展KMP算法的,有些使用Manacher算法的,看到KMP我就感觉很不爽,那个东西当初搞了好久都没有搞明白,最后看了一下
Manacher算法的思路和方法,代码比较简单,只是原理不是很清楚,先暂时放在这里!
http://blog.csdn.net/ggggiqnypgjg/article/details/6645824
上面的这篇博客是讲Manacher算法思想的,讲的还算不错。
代码模板:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
//数组必须要开到150000以上才能过,至于为什么maxn为什么要这么大,不是很清楚
const int maxn=150010;
int rad[maxn];
char str[maxn],s[2*maxn+2];
//函数中参数说明:若原字符串是"abcd",
//则str为"$#a#b#c#d#",n为加上'#'以后的字符串长度
//数组rad[]中记录的是回文子串的半径
void Manacher(int rad[],char str[],int n)
{
int i,mx=0,id;
for(i=1;i<n;i++)
{
if(mx>i) rad[i]=min(rad[2*id-i],mx-i);
else rad[i]=1;
for(;str[i+rad[i]]==str[i-rad[i]];rad[i]++)
;
if(mx<rad[i]+i)
{
mx=rad[i]+i;
id=i;
}
}
}
int main()
{
while(scanf("%s",str)!=EOF)
{
//memset(rad,0,sizeof(rad));
int len=strlen(str);
s[0]='$',s[1]='#';
for(int i=0;i<=len;i++)
{
s[2*i+2]=str[i];
s[2*i+3]='#';
}
Manacher(rad,s,2*len+2);
//找出最长的回文子串的长度
int ans=1;
for(int i=0;i<2*len+2;i++)
ans=max(ans,rad[i]);
printf("%d\n",ans-1);
}
return 0;
}