一:返回最长回文串的字符个数
#include<iostream>
#include<cstdio>
# include<string.h>
using namespace std;
const int maxn = 100010;
char ma[maxn << 1],s[maxn];
int mp[maxn << 1];
void Manacher(char s[],int len)
{
int l = 0;
ma[l++] = '$';
ma[l++] = '#';
for(int i = 0;i < len; i++)
{
ma[l++] = s[i];
ma[l++] = '#';
}
ma[l] = 0;
/*i代表此刻字符串的位置
* id代表此时最大回文子串的中心
* mx代表当前得到的最大回文子串的右边界*/
int mx = 0;
int id = 0;
for(int i = 0;i < l; i++)
{
mp[i] = mx > i ? min(mp[id * 2 - 1],mx - i) : 1;
while(ma[i + mp[i]] == ma[i - mp[i]])
mp[i]++;
if(i + mp[i] > mx)
{
mx = i + mp[i];
id = i;
}
}
}
int main()
{
while(scanf("%s",s) == 1)
{
int len = strlen(s);
Manacher(s,len);
int ans = 0;
for(int i = 0;i < 2 * len + 2; i++)
ans = max(ans,mp[i] - 1);
printf("%d\n",ans);
}
}
二:返回最长回文串
还有用后缀数组解决最长回文串的问题:文章第五题
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void findBMstr(string str0){
string str;
str += "$#";
int n=str0.size();
for(int i = 0; i < n; i++){
str += str0[i];
str += "#";
}
int len=str.size();
int *p = new int[len + 1];
memset(p, 0, sizeof(p));
int mx = 0, id = 0;
for(int i = 1; i <= len; i++){
if(mx > i){
p[i] = (p[2*id - i] < (mx - i) ? p[2*id - i] : (mx - i));
}
else{
p[i] = 1;
}
while(str[i - p[i]] == str[i + p[i]])
p[i]++;
if(i + p[i] > mx){
mx = i + p[i];
id = i;
}
}
int Max = 0, ii;
for(int i = 1; i < len; i++){
if(p[i] > Max){
ii = i;
Max = p[i];
}
}
Max--;
int s = ii - Max ;
int e = ii + Max;
for(int i = s; i <= e; i++){
if(str[i] != '#'){
cout << str[i];
}
}
cout << endl;
delete p;
}
int main()
{
string str;
cin>>str;
findBMstr(str);
return 0;
}