【数组和字符串】3.3最长回文串

样例:
Input:
Confuciuss say:Madom,I’m Adam.
Output:
Madam,I’m Adam.

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define MAXN 5000+10
char buf[MAXN],s[MAXN];
int p[MAXN];
//用P[i]来保存s[i]在buf中的位置 
int main()
{
    int n,m=0,max=0,x,y;
    int i,j,k;
    fgets(buf,sizeof(s),stdin);
    //读取完整的一行储存在字符数组buf中; 
    //该调用从标准输入流 stdin(也就是键盘输入)
    //读入 s 数组的大小(sizeof(s))再减 1 的长度的字符到 buf 所指的内存空间中
    n=strlen(buf);
    for(i=0;i<n;i++)
    {
        if(isalpha(buf[i]))
        {
            p[m]=i;//用P[i]来保存s[i]在buf中的位置 
            s[m++]=toupper(buf[i]);
        }
        //isalpha 判断buf[i]是否为数组  toupper返回大写字母  头文件:ctype.h; 
        //同时m保存字母数; 
    } 

    /*
    //枚举回文串的起点和终点并判断是否为回文串; 
    for(i=0;i<m;i++)
    {
        for(j=i;j<m;j++)
        {
            //判断s是否为回文串 
            int ok=1;
            //引入变量 ok 参与判断 
            for(k=i;k<=j;k++)
            {
                if(s[k]!=s[i+j-k]) ok=0;
            }
            if(ok&&j-i+1>max) max=j-i+1;
            //利用“当前最大值”变量 max 来保存当前发现的最长回文串的长度;  
        }
    }
    printf("max=%d\n",max);
    */

    //上述代码可获得最长回文串长度;


    //由于字符可多达5000个,由生成一个5000个字符'a'的字符串可以发现程序效率会太低,运行速度过慢
    //则我们可以枚举回文串的额中间位置'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;
            if(j*2+1>max)
            {
                max=j*2+1;
                x=p[i-j];
                y=p[i+j];
                //在更新max的同时把p[i]和p[j]分别保存在x,y中,最后输出buf[x]和buf[y]中的所有字符; 
            }
        }
        for(j=0;i-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; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值