C-最长回文子串(2)

在上一篇的文章中说到了,最长回文子串的问题,并且提到了基本的解决办法,即暴力求解法。效率O(N^3)

中心法求最长回文子串

我们知道回文字符串是以字符串中心对称的,如abba以及aba等。一个更好的办法是从中间开始判断,因为回文字符串以字符串中心对称。一个长度为N的字符串可能的对称中心有2N-1个,至于这里为什么是2N-1而不是N个,是因为可能对称的点可能是两个字符之间,比如abba的对称点就是第一个字母b和第二个字母b的中间。因此可以依次对2N-1个中心点进行判断,求出最长的回文字符串即可

所以,要考虑回文是奇数还是偶数的情况。

#include<stdio.h>

#include<stdlib.h>

#include<ctype.h>

#define MAXN 500+10

char buf[MAXN],s[MAXN];

int index[MAXN];



int main()

{

    int i,j;

    int start = 0,end = 0;

    int max = 1;

    int m = 0,n;

    fgets(buf,sizeof(s),stdin);

    n = strlen(buf);



//剔除其中的非字母字符,并且全部转换为大写字母

    for(i = 0;i<n;i++)

    {

        if(isalpha(buf[i]))

        {

            index[m] = i;

            s[m++] = toupper(buf[i]);

        }

    }

    for(i = 0;i<m;i++)

    {

        /**奇数情况下*/

        /**以i为中心,向左向右移动j,判断是否相同*/

        /**这样求出的长度就是2*j+i*/

        for(j = 0;i+j<m && i-j>=0;j++)

        {

            if(s[i-j] != s[j+i]) break;

            if(2*j+1 > max)

            {

                 max = 2*j+1;

                 start = i-j;

                 end = i+j;

            }

        }

        /**偶数情况下*/

        /**以i 和 i+1为中心,左右移动j,再判断*/

        for(j = 0;i-j>=0 && i+1+j<m;j++)

        {

            if(s[i-j] != s[i+1+j]) break;

            if(2*j+2 > max)

            {

                 max = 2*j+2;

                 start = i-j;

                 end = i+j+1;

            }

        }

    }

    printf("max = %d\n",max);

    for(i = index[start];i<=index[end];i++)

        printf("%c",buf[i]);

    putchar(10);



    return 0;

}
View Code

 

你可能感兴趣的:(回文)