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是因为数据还不算太大~

时间: 2024-10-11 12:02:39

2238"回文字串"报告的相关文章

最长回文字串理解(学习Manacher&#39;s algorithm)

关于字符串的子串问题,我们经常需要利用的是已经访问的部分的信息,来降低复杂度,和提高效率:在求最长回文子串的问题中,Manacher's algorithm提供了一种很好的机制,虽然部分地方不太容易理解 先说下核心的思想:先对原字符串进行预处理,将字符串"abc"转换为"$#a#b#c#"的形式,既避免了访问越界的问题,又保证每一个字符有至少一个对称的串(真字符,或是假的“#”) 预留两对变量(当前得到的中心位置“center”,和字符串右侧最远位置“R”,以及对称

最长回文字串 (The longest palindrome substring)

这两天去学了一下,觉得下面那篇文章写的很好,有例子,比较容易懂,所以转一下. 以下内容来自:hihoCoder: 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?” 小Ho奇怪的问道:“什么叫做最长回文子串呢?” 小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文

Hdu 3068 最长回文字串Manacher算法

题目链接 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7976    Accepted Submission(s): 2735 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输入

P1435 回文字串

P1435 回文字串 题目背景 IOI2000第一题 题目描述 回文词是一种对称的字符串.任意给定一个字符串,通过插入若干字符,都可以变成回文词.此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数. 比如 "Ab3bd"插入2个字符后可以变成回文词"dAb3bAd"或"Adb3bdA",但是插入少于2个的字符无法变成回文词. 注:此问题区分大小写 输入输出格式 输入格式: 一个字符串(0<strlen<=1000) 输出格

最长回文字串

区别于最长公共字串,下面是最长公共字串的算法,利用DP(动态规划): void LCS_dp(char * X, int xlen, char * Y, int ylen) { maxlen = maxindex = 0; for(int i = 0; i < xlen; ++i) { for(int j = 0; j < ylen; ++j) { if(X[i] == Y[j]) { if(i && j) { dp[i][j] = dp[i-1][j-1] + 1; } if

回文字串的问题

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

最长回文字串(hdu 3068)

原题链接http://acm.hdu.edu.cn/showproblem.php?pid=3068 查找字符串中最长的回文串,我们用到manachar算法. 要实现manachar算法我们有有两步要做 1:对字符串进行处理,把所有的字符串的长度统一化为奇数.. 1 int l=0; 2 int ans=0; 3 Ma[l++]='$'; 4 Ma[l++]='#'; 5 for(int i=0;i<len;i++) 6 { 7 Ma[l++]=s[i]; 8 Ma[l++]='#'; 9 }

ural 1297 O(nlogn) 后缀数组求最长回文字串

把原串复制一份反过来接在原串后面,中间用没出现过的字符隔开,然后跑后缀数组,在原创枚举每一个位为回文中心(分奇偶讨论),则回文串长度相当于原串与反串对应位置的lcp,所以先用ST预处理,然后查询.复杂度O(nlogn) #include<iostream> #include<cstring> #include<set> #include<map> #include<cmath> #include<stack> #include<

【POJ3974】最长回文字串

在这里采用的是哈希+二分的方法. 根据回文串的性质可知,可以将回文分成奇回文和偶回文分别进行处理. 对于奇回文来说,每次枚举的端点一定是重合的,因此只需计算出端点左右公共的长度是多少即可,因此二分的是以该枚举点为中心的左半边共有多少个字符. 对于偶回文来说,每次枚举的端点不一定是相等的,因此在二分的是以当前枚举点开始(包括当前枚举点)向右最多有多少个字符. 另外,之所以能够采用二分是因为当前需判断的左右串是否是回文这个问题具有单调性,即:从最大点处开始之后均不是回文,小于最大值均是回文. 在比较