思路:三重循环
外层确定回文子串的起点
里层确定回文子串的终点
最内层给出一次遍历确定是否是回文子串
for(i=0;i<m;i++)
for(j=i+1;j<m;j++)
{
if(满足条件)记录回文长度
}
#include<iostream>
#include<string.h>
#include<ctype.h>
using namespace std;
#define MAX 5000+10
char buf[MAX],s[MAX];
int main()
{
int n,m=0,max=0;
int i,j,k;
fgets(buf,MAX,stdin);
for(i=0;i<sizeof(buf);i++)
if(isalpha(buf[i])) s[m++]=toupper(buf[i]);
for(i=0;i<m;i++)
for(j=i+1;j<m;j++)
{
int ok=1;//注意最内一层判断条件的书写
for(k=i;k<j;k++)
if(s[k] != s[j+i-k])
{ok=0;break;}
if(ok && j-i+1>max)
max=j-i+1;
}
cout<<"max="<<max<<endl;
system("pause");
return 0;
}
改进方式:
枚举回文串的中间位置i,然后不断往外扩展,直到有字符不同,这样只需要两层循环
#include<iostream>
#include<string.h>
#include<ctype.h>
using namespace std;
#define MAX 5000+10
char buf[MAX],s[MAX];
int main()
{
int m=0,max=0;
int i,j,k;
int x=0,y=0;
fgets(buf,MAX,stdin);
for(i=0;i<sizeof(buf);i++)
if(isalpha(buf[i])) s[m++]=toupper(buf[i]);
for(i=0;i<m;i++)
for(j=0;i-j>=0 && i+j<m;j++)
{
if(s[i-j] != s[i+j]) break;// 这句话的意思是,只有满足情况才更新max,记录起始和终止位置。如果不满情况,则不记录
if(j*2+1>max) {max=j*2+1;x=i-j;y=i+j;}
}
for(i=0;i<m;i++)
for(j=0;i-j>=0 && i+1+j<m;j++)
{
if(s[i-j] != s[i+1+j]) break;
if(j*2+2>max) {max=j*2+2;x=i-j;y=i+1+j;}
}
cout<<"max="<<max<<endl;
cout<<"最长回文子串是:";
for(i=x;i<=y;i++)
cout<<buf[i];
cout<<endl;
system("pause");
return 0;
}