http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/
原文说的很清楚,Manacher算法就是O(n)来求一个字符串S的最长回文串的。
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm> //max min函数包含在这个里面。。?
using namespace std;
#define LEN 110010
char s[LEN],s1[LEN*2];//长度一定要*2 !!
int p[LEN*2];
int n;
void pre()
{
n=strlen(s);
s1[0]='$';//防止比较的时候越界
s1[1]='#';
for (int i=0;i<n;i++)
{
s1[(i+1)*2]=s[i];
s1[(i+1)*2+1]='#';
}
n=n*2+2;
s1[n]=0;
}
void kp()
{
int mx=0;
int id;
for (int i=1;i<=n;i++)
{
if (mx>i)
p[i]=min(p[2*id-i],mx-i); //这里的两种情况使得算法O(n)
else
p[i]=1;
while(s1[i-p[i]]==s1[i+p[i]]) p[i]++;
if (i+p[i]>mx)
{
mx=i+p[i];
id=i;
}
}
}
void pt()
{
int ans=0;
for (int i=1;i<=n;i++)
ans=max(ans,p[i]-1);
printf("%d\n",ans);
}
int main()
{
while (~scanf("%s",s))
{
pre();
kp();
pt();
}
}
ural1297
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;
#define LEN 110010
char s[LEN],s1[LEN*2];//长度一定要*2 !!
int p[LEN*2];
int n;
void pre()
{
n=strlen(s);
s1[0]='$';//防止比较的时候越界
s1[1]='#';
for (int i=0;i<n;i++)
{
s1[(i+1)*2]=s[i];
s1[(i+1)*2+1]='#';
}
n=n*2+2;
s1[n]=0;
}
void kp()
{
int mx=0;
int id;
for (int i=1;i<=n;i++)
{
if (mx>i)
p[i]=min(p[2*id-i],mx-i);
else
p[i]=1;
while(s1[i-p[i]]==s1[i+p[i]]) p[i]++;
if (i+p[i]>mx)
{
mx=i+p[i];
id=i;
}
}
}
void pt()
{
int ans=0;
int id;
for (int i=1;i<=n;i++)
if (ans<p[i])
{
ans=p[i];
id=i;
}
for (int i=id-ans+1;i<=id+ans-1;i++)
if (s1[i]!='#') cout<<s1[i];
}
int main()
{
while (~scanf("%s",s))
{
pre();
kp();
pt();
}
}
感觉很奇怪,原文作者说他的代码有bug,然而我没加str[]清空,似乎没有bug。。?