题目描述
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同。如abba和yyxyy。在判断回文时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。
输入
一行字符串,字符串长度不超过5000。
输出
字符串中的最长回文子串。
样例输入
Confuciuss say:Madam,I'm Adam.
样例输出
Madam,I'm Adam
前半部分进行字符提取,后半部分和书上模板一模一样,很容易看懂。
#include<bits/stdc++.h>
using namespace std;
const int maxn=5010;
int dp[maxn][maxn],p[maxn];
char S[maxn];
int main()
{
string str;
getline(cin,str);
memset(dp,0,sizeof(dp));
int len=str.size();
int num=0;
for(int i=0;i<len;i++)
{
if(isalpha(str[i]))
{
S[num]=toupper(str[i]);
p[num++]=i;
}
else if(isdigit(str[i]))
{
S[num]=str[i];
p[num++]=i;
}
}
for(int i=0;i<num;i++)
{
dp[i][i]=1;
if(i<num-1&&S[i]==S[i+1])
{
dp[i][i+1]=1;
}
}
int x=0,y=0;
for(int i=3;i<=num;i++)
{
for(int j=0;j+i-1<num;j++)
{
int k=j+i-1;
if(S[k]==S[j]&&dp[j+1][k-1]==1)
{
dp[j][k]=1;
x=p[j];y=p[k];
}
}
}
for(int i=x;i<=y;i++)
cout<<str[i];
return 0;
}