数组:查找最长回文串(1)

方法:分奇数偶数从中心扩散

困难在于计算总数与每个比较的地方都只考虑数字。

任务描述

本关任务:编写一个程序,寻找一篇英文文章中最长的回文字符串。回文字符串是具有回文特性的字符串:即该字符串从左向右读,与从右向左读都一样。

编程要求

根据提示,在右侧编辑器补充代码,用户输入的文章不会超过10000字符。这个文件可能一行或多行,但是每行都不超过80个字符(不包括最后的换行符)。在寻找回文时只考虑字母 ‘A’ - ‘Z’ 和 ‘a’ - ‘z’ ,忽略其他字符(例如:标点符号,空格等)。输出的第一行应该包括找到的最长的回文的长度。然后是这个回文的原文(没有除去标点符号,空格等),但是从字母开始,到字母结束。如果有多个回文长度都等于最大值,输出最前面出现的那一个。

测试说明

平台会对你编写的代码进行测试:

测试输入: Hello,world! Dlrow,olleh! Helloh,world! Dlrow,holleh! Helloah,world! Dlrow,haolleh! Hellohwaha,world! Dlrow,ahawholleh!

预期输出: 38 w,holleh! Helloah,world! Dlrow,haolleh! Hellohw

#include <iostream>
using namespace std;
int main()
{
    char a[10000]={0};//原字符串数组
    int b[10000]={0};//begin
    int l[10000]={0};//last
    char ch;
    int i=0,j=0;
    while((ch=cin.get())!=EOF) //写入字符串
    {a[i]=ch;i++;}
    i-=1;//总共为下标是i
    int t=1;
    int flag=0;int m=0;
    int begin_p=0,last_p=0;
    int even=0;
    for(j=0;j<i;j++)
    {
        even=0;flag=0;t=1;
        if(a[j]<'A'||(a[j]>'Z'&&a[j]<'a')||a[j]>'z')continue;

        while(a[j+t]<'A'||(a[j+t]>'Z'&&a[j+t]<'a')||a[j+t]>'z'){t++;}//考虑j+1与j之间有非字母字符的情况
        if(a[j]==a[j+t]||a[j]==a[j+t]+32||a[j]==a[j+t]-32) {even=1;}

        if(even==1)//even
        {
            if(j==0)
            {begin_p=0;last_p=j+t;flag=1;}//前两个字符构成了回文数
            else
            {
                int t1=1,t2=1;
                while(j-t1>=0&&j+t+t2<=i)
                {
                    if(a[j-t1]<'A'||(a[j-t1]>'Z'&&a[j-t1]<'a')||a[j-t1]>'z')//t1不是字符,往前取
                    {t1++;continue;}
                    if(a[j+t+t2]<'A'||(a[j+t+t2]>'Z'&&a[j+t+t2]<'a')||a[j+t+t2]>'z')//t1不是字符,往后取
                    {t2++;continue;}
                    if(a[j-t1]==a[j+t+t2]||a[j-t1]==a[j+t+t2]+32||a[j-t1]==a[j+t+t2]-32)//相等,大小写忽略
                    {
                        begin_p=j-t1;last_p=j+t+t2;
                        flag=1;t1++;t2++;
                    }//if
                    else break;//得到了bp和lp
                }//while(扩展比较)
            }//else(index不是第一项)
        }//if(even)

        else//odd
        {
            if(j==0){begin_p=last_p=0;flag=1;}
            else
            {
                int t1=1,t2=1;
                while(j-t1>=0&&j+t2<=i)
                {
                    if(a[j-t1]<'A'||(a[j-t1]>'Z'&&a[j-t1]<'a')||a[j-t1]>'z')//index左侧不是字符,往前取
                    {t1++;continue;}
                    if(a[j+t2]<'A'||(a[j+t2]>'Z'&&a[j+t2]<'a')||a[j+t2]>'z')//index左侧不是字符,往后取
                    {t2++;continue;}
                    if(a[j-t1]==a[j+t2]||a[j-t1]==a[j+t2]+32||a[j-t1]==a[j+t2]-32)//相等
                    {
                        begin_p=j-t1;last_p=j+t2;
                        flag=1;t1++;t2++;
                    }
                    else break;
                }//while
            }//else(not the first)
        }//else(odd)
        if(flag!=0)
        {
            b[m]=begin_p; l[m]=last_p;
            m++;
        }
    }//for

    int longest=0;
    int y=0,length1=0;
    for(int z=0;z<m;z++)
    {
        for(int w=b[z];w<=l[z];w++)
            if(a[w]>='A'&&a[w]<='Z'||a[w]>='a'&&a[w]<='z') length1+=1;
        if(length1>longest){longest=length1;y=z;}
        length1=0;
    }

    int length =0;
    for(int w=b[y];w<=l[y];w++)
        if(a[w]>='A'&&a[w]<='Z'||a[w]>='a'&&a[w]<='z') length+=1;

    cout<<length<<endl;
    for(int w=b[y];w<=l[y];w++)
        cout<<a[w];
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值