• 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
  • 相关阅读:
    book pile SGU
    Inversions SGU
    蒟蒻LQL的博客
    控制台注入DLL代码
    Windows消息类型
    windows编程中的数据类型
    单链表的创建与遍历
    定义函数指针
    启动外部程序
    dll共享段中一些需要注意的问题
  • 原文地址:https://www.cnblogs.com/plxx/p/3574846.html
Copyright © 2020-2023  润新知