最长回文子串

学习自《算法竞赛入门经典》

/*  
* 输入一个字符串,求出其中最长的回文子串。
*子串的含义是:在原串中连续出现的字符串片段。 在判断时,应该忽略所有标点符号和空格 
*且忽略大小写,但输出应保持原样(在回文串的首部和尾部不要输出多余字符)。
*输入字符长度不超过5000, 且占据单独的一行。
*应该输出最长回文串,如果有多个,输出起始位置最靠左的。 
*样例输入:Confuciuss say:Madam,I'm Adam. 
*样例输出:Madam,I'm Adam 
*/  

#include <stdio.h>
#include <string.h>
#include <ctype.h>	//用到isalpha、touuper等工具

#define MAXN 5010

char buf[MAXN],s[MAXN];	//分别是原数组,经过预处理以后的数组
int pos[MAXN];			//用于保存s[i]在buf中的位置 

int main()
{
	int n,m=0,max=0,x,y;
	int i,j,k;
	fgets(buf,sizeof(buf),stdin);//从标准输入流中读取一整行的内容放在buf中(包括换行符)	
	n= strlen(buf);
	for(i=0;i<n;i++)
	{
		if(isalpha(buf[i]))	//构造一个新的字符串,把标点符号过滤掉,随便把小写字母变为大写
		{
			pos[m]=i;		//保存s[m]在buf的位置 
			s[m++]=toupper(buf[i]);
		}
	} 
	
	for(i=0;i<m;i++)	//遍历字符串s,以i为"中间"位置,然后根据j的值不断向两边扩展  
	{
		//这个for循环遍历的子串长度为奇数 
		for(j=0;i-j>=0 && i+j<m;j++)	//i-j>=0表示i到j的距离不能上溢
										//i+j<m表示i再加j个位置没有超过字符串s的总长
		{
			if(s[i-j]!=s[i+j])	break;	//如果左右对应位置不匹配 
			if(j*2+1>max)
			{
				max=j*2+1;		//更新max 
				x=pos[i-j];		//记录子串范围
				y=pos[i+j];
			}
		}
		
		//这个for循环遍历的子串长度为偶数             
		for(j=0;i-j>=0 && i+j<m;j++)
		{
			//中间点i取子串长度的中点,导致两边长度不均,右边的距离应该再加1
			if(s[i-j]!=s[i+j+1]) break;
			if(j*2+2>max)
			{
				max=j*2+2;
				x=pos[i-j];
				y=pos[i+j+1];
			}
		}
	}
	
	for(i=x;i<=y;i++)	//把最长回文子串输出 
		printf("%c",buf[i]);
	return 0;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值