题目:输入一个字符串,求出其中最长的回文子串,字串的含义是:在原串中连续出现的字符串片段。回文的含义是:正着看和倒着看相同,如abba,yyxyy。在判断时,应该忽略所有标点符号和空格,且忽略大小写,但输出应该保持原样(在回文串的首部和尾部不要数尺多余字符),输入字符串长度不超过5000,且占据单独的一行。应该输出最长的回文串,如果有多个,输出起始位置最靠左的
样例输入:Confuciuss say:Madam,I'm Adam.
样例输出:Madam,I'm Adam
这道题初看感觉非常的麻烦,因为要处理的问题太多,首先是怎么读入一整行包含有空格各种符号的字符串,用scanf是不行的,因为scanf一遇到空格或者Tab就会中止,所以得换其他的输入方式,我用的是ffgets()函数,fgets(buf,MAXN,fin)读取完整的一行,其中buf的声明是char buf[MAXN],这个函数读取不超过MAXN-1个字符,然后在末尾添上结束符\0,因此不会出现越界的情况。然后还要解决“判断时忽略标点,输出时却要按原样”的问题,首先,输入的标点符号不能直接删除,否则就没法按原样输出了,这里有一个通用的方案:预处理。构造一个新的字符串,不包含原来的标点符号,且所有的字符变成大写
这里有个函数很好用,一个是isalpha(x)函数,它可以用来判断x是否是字符,包含在头文件#include<ctype.h>中,下面是代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX 10000
char buf[MAX],s[MAX];
int p[MAX];//记录字符在原串中的位置
int main()
{
int n,m=0,max=0,x,y;
int i,j;
fgets(buf,sizeof(buf),stdin);
n=strlen(buf);
for(i=0;i<n;i++){
if(isalpha(buf[i])){
p[m]=i;
s[m++]=toupper(buf[i]);
}
}
for(i=0;i<m;i++)
{
//偶数
for(j=0;i+j<m&&i-j>0;j++){
if(s[i-j]!=s[i+j]) break;
if(j*2+1>max){
max=j*2+1;
x=p[i-j];
y=p[i+j];
}
}
//奇数
for(j=0;i+j+1<m;j++){
if(s[i-j]!=s[i+j+1]) break;
if(j*2+2>max){
max=j*2+2;
x=p[i-j];
y=p[i+j+1];
}
}
}
for(i=x;i<=y;i++){
printf("%c",buf[i]);
}
printf("\n");
return 0;
}