一.中心扩展法(模板)
#include <bits/stdc++.h>
#include <string>
//求回文 -- 中心扩展法
using namespace std;
//选定字符串s,左边界left,右边界right
int expand_stringCenter(string s,int left,int right){
while (left >= 0 && right <s.length() && s[left] == s[right])
{
left--;
right++;
}
return right-left-1;//(right-1)-(left+1)+1;
}
//中心扩展法的核心
string Palindrom(string s)
{
if(s.empty()) return ""; //如果传入空字符串
int start = 0,end = 0; //回文的起始索引和结束索引
for(int i = 0;i < s.length();i++){
int len_1 = expand_stringCenter(s,i,i); //如果这回文是有中心的。即奇数
int len_2 = expand_stringCenter(s,i,i+1); //如果这回文是偶数的,那就是找不到回文中心
int len = max(len_1,len_2); //判断回文是奇数还是偶数的
if(len > end-start+1)//相同长度更新后者,覆盖结果
{
start = i-(len-1)/2;
end = i +len/2;
}
//如果是if(len > end-start),那就返回第一个最长回文串的子串
}
return s.substr(start,end-start+1);
}
int main() {
string s;
s = "ababd";
cout << "最长回文子串:" << Palindrom(s) ;
return 0;
}
补充:关于substr的用法
#include <iostream>
#include <string>
using namespace std;
int main() {
string str = "Hello, World!";
cout << str.substr(7) << endl; // 输出: World!
cout << str.substr(7, 5) << endl; // 输出: World
return 0;
}
二.manacher算法(模板)
#include <bits/stdc++.h>
#include <vector>
#include <string>
//manacher算法,要点在于预处理和回文寻找
using namespace std;
//预处理字符串
string Get_nowstring(string s){
string t = "#";
for(int i = 0;s[i];++i)
{
(t+=s[i])+="#";
}
return t;
}
/*
a b a c
# a # b # a # c
*/
string Palindrom(string s){
string T = Get_nowstring(s);
int n = T.size();
vector<int> P(n,0);//存储每个位置的回文半径
int C = 0,R = 0;//center radius(已知的字符串的右边界)
for(int i = 0;i<n;i++)
{
int Symmetry = 2*C -i; //i关于C的对称点
if(i<R) P[i]=min(R-i,P[Symmetry]);
int left = i-(P[i]+1);
int right = i+(P[i]+1);
while(left>=0 && right < T.size() && T[left] == T[right])
{
left--;
right++;
P[i]++;
}
if(i+P[i]>R) //已知字符串右边界更新
{
C = i;
R = i+P[i];
}
}
int maxlen=0,center = 0;
for(int i = 0;i<n;i++)
{
if(P[i]>=maxlen) maxlen=P[i],center=i;
}
//处理预处理字符
int start = (center - maxlen)/2;
return s.substr(start,maxlen);
}
int main() {
string s = "ababd";
cout << "最长回文子串:" << Palindrom(s) ;
return 0;
}