首页 > 代码库 > 2238"回文字串"报告

2238"回文字串"报告

题目描述:

回文串,就是从前往后和从后往前看都是一样的字符串。那么现在给你一个字符串,请你找出该字符串中,长度最大的一个回文子串。

输入描述:

有且仅有一个仅包含小写字母的字符串,保证其长度不超过5000

输出描述:

有且仅有一个正整数,表示最长回文子串的长度

输入样例:

abccbxyz

输出样例:

4

分析:

  我的算法算是比较暴力的。这道题目中,需要输出最长的回文字串的长度,我的想法是从最长的长度开始寻找是否有回文字串符合这个长度,如果没有,则从次长的长度寻找是否有符合长度的回文字串。比如说,给定abccbxyz,它们分别对应a[0]-a[7],我们先从长度最长,也就是8开始查找,然后从a[0]开始寻找,如果a[0]和它后面的第(0 + 8 - 1)个数字相等,那么这个数字可能是回文字串,此时,从a[0 + 1]和a[8 - 2]开始比较,也就是字符串往中间收,如果有一组对应的字符不相等,那么就不是回文字串,接着就从a[1]为起点开始和a[1 + 8 - 1]开始比较,之后的过程和前面一样,当找到符合长度的回文字串是,就可以输出这个长度,然后结束。需要注意的是,每一个回文字串的起点的范围是:0-p - k,其中p是总字符串的长度,k是要寻找的长度,因为一旦起点大于p-k,那么终点为p-k+k等于p,而数组是这个下标代表的是‘\0‘。接下来,代码就很容易写出来了。

代码:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char a[5001];
    int k,l,p,flag1,flag2,i,j,m,flag,flag3;
    scanf ("%s",a);
    p = strlen(a);//算出字符串的长度
    for (k = p; k >= 1; k--)//k为需要寻找符合长度的回文字串的长度,从后往前找
    {
        flag3 = 0;//标记是否找到了符合长度的回文字串
        for (i = 0; i <= p - k; i++)//起点的范围从0到p-k
        {
            if(a[i] == a[i + k - 1])//起点和终点相等,就需要开始比较这个字串
            {
                flag = 1;
                if(k > 3)//当字串长度小于等于3时,如果起点相等,那么一定是回文串,则不需要进行下面的操作
                {
                  for (flag1 = i + 1,flag2 = i + k - 2,m = i + k / 2 - 1; flag1 <= m; flag1++,flag2--)//从起点和终点往中间收
                  {
                    if(a[flag1] != a[flag2])//有一组对应的不相等,则不是回文串
                    {
                        flag = 0;
                        break;
                    }

                  }
                }
                else//k <= 3,当字串长度小于等于3时,如果起点相等,那么一定是回文串
                {
                    flag3 = 1;
                    break;
                }
                if(flag)
                {
                    flag3 = 1;//当没有对应的不相等,那么是回文串,进行标记表示找到了
                    break;
                }
            }
        }
        if(flag3)//找到了最长的回文字串,输出该长度,结束
        {
            printf ("%d\n",k);
            break;
        }
    }

    return 0;
}

总结:这种算法比较好理解,但也比较复杂,因为其时间复杂度是O(n^2),能A是因为数据还不算太大~

2238"回文字串"报告