题目描述
输入一个字符串,求出其中最长的回文子串。子串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同。如abba和yyxyy。在判断回文时,应该忽略所有标点符号和空格,且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的。
输入
一行字符串,字符串长度不超过5000。
输出
字符串中的最长回文子串。
样例输入
Confuciuss say:Madam,I'm Adam.
样例输出
Madam,I'm Adam
#include<iostream>
#include<vector>
#include<string>
#include<cstdio>
#include<ctype.h>
using namespace std;
struct node
{
int ch;
int index;
};
int main()
{
string str_original;
vector<node> str_cmp;
int index_min=5010;
int index_max;
int len_max = 0;
int dp[5010][5010];
getline(cin,str_original);
int len_original = str_original.size();
for (int i = 0; i < len_original; i++)
{
char ch = str_original[i];
if (isalpha(ch) || isdigit(ch))
{
if (isalpha(ch))
{
ch = toupper(str_original[i]);
}
int c = int(ch);
node temp;
temp.ch = c;
temp.index = i;
str_cmp.push_back(temp);
}
}
int len = str_cmp.size();
if (len > 1)
{
for (int i = 0; i < len; i++)
{
dp[i][i] = 1;
}
for (int i = 0; i < len - 1; i++)
{
if (str_cmp[i].ch == str_cmp[i + 1].ch)
{
dp[i][i + 1] = 2;
len_max = 2;
if (str_cmp[i].index < index_min)
{
index_min = str_cmp[i].index;
index_max = str_cmp[i+1].index;
}
}
else
{
dp[i][i + 1] = 0;
}
}
for (int inc = 2; inc < len; inc++)
{
for (int i = 0; i < len - inc; i++)
{
node a = str_cmp[i];
node b = str_cmp[i + inc];
if (a.ch == b.ch && dp[i+1][i + inc-1]>0)
{
dp[i][i + inc] = dp[i + 1][i + inc - 1] + 2;
if (dp[i][i + inc] > len_max)
{
len_max = dp[i][i + inc];
index_min = a.index;
index_max = b.index;
}
else if(dp[i][i + inc] == len_max)
{
if (a.index < index_min)
{
index_min = a.index;
index_max = b.index;
}
}
}
else
{
dp[i][i + inc] = 0;
}
}
}
for(int i=index_min;i<=index_max;i++)
{
cout << str_original[i];
}
}
return 0;
}