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
",max);
    for(i = index[start];i<=index[end];i++)
        printf("%c",buf[i]);
    putchar(10);

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/plxx/p/3574846.html