最大回文子串

题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。
比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。


主要是参考了一下两篇文章:

http://blog.csdn.net/qitian0008/article/details/8042558

http://www.cnblogs.com/eric-blog/archive/2012/05/03/2481510.html

其中常规的方法,就是用一个i从左到右进行遍历,当i指向某个值的时候,以i为中心,逐个比较左右两个的字符是否相等。

这样就可以找到一个回文,以及他的长度。

但是,这样做的时候,是有重复计算的过程的。比如你找到一个回文,这个回文是左右对称的,那么你在计算右边范围内的某个字符,计算这个字符为中心的回文长度的时候,就可以利用他对称的左边的字符的回文长度,这样就可以实现简化,也就那个O(n)算法的思想。

但是计算回文的时候,有一个小问题,就是回文是奇数还是偶数,有个避免这种判断的方法就是在每个字幕中间插入#号,这样所有的都是奇数了。

好了,所有的问题都解决了,看代码吧。

#include <iostream>
using namespace std;

int getMaxHuiWenChar1(char *p,int len)  
{  
    int nLen=2*len+3;  
    char *str =new char[nLen];  
    int i=0;  
    int max=0;  
    int j=0,x,y;  
    str[0]='$';  
    str[1]='#';  
    for(;i<len;i++)
    {  
        str[i*2+2]=p[i];  
        str[i*2+3]='#';  
    }  
    str[nLen-1]=0;  

    for(i=0;i<nLen;i++)  
    {  
        cout<<str[i];  
    }  
    cout<<endl;  

    for(i=1;i<nLen;i++)  
    {  
        for(int j=0; i-j>0&&i+j<nLen; j++)
        {
            if(str[i-j]!=str[i+j])
                break;
            else
            {
                if(max<j)
                {
                    max=j;  
                    x=i-j;  
                    y=i+j;  
                }
            }
        }
    }  

    for(int k=x+1;k<=y-1;k+=2)//打印出回文  
    {  
        cout<<str[k];  
    }  
    return max;  
}  
int min(int a, int b)
{
    return a<b?a:b;
}
int getMaxHuiWenChar2(char *s,int len)  
{  
    int nLen=2*len+3;  
    char *str =new char[nLen];  
    int i=0;  
    int max=0;  
    str[0]='$';  
    str[1]='#';  
    for(;i<len;i++)  
    {  
        str[i*2+2]=s[i];  
        str[i*2+3]='#';  
    }  
    str[nLen-1]=0;  
    int *p=new int[nLen];//定义一个用于标记的int数组  

    for(i=1;i<nLen;i++)  
    {  
        cout<<str[i];  
        p[i]=0;  
    }  
    cout<<endl;  

    int id=0;  
    for(i=1; i<nLen; i++)  
    {  
        if( max > i )  
            p[i] = min( p[2*id-i], p[id]+id-i  );
        else  
            p[i] = 1;  
        for(; str[i+p[i]] == str[i-p[i]]; p[i]++)  
            NULL;  
        if( p[i] + i > max )  
        {  
            max = p[i] + i;  
            id = i;  
        }  
    }  

    int mx=0;  
    for(i=1;i<nLen;i++)  
    {  
        if(mx<p[i]-1)  
            mx=p[i]-1;  
    }  
    return mx;  
}  

int main(int argc, char* argv[])  
{  
    char *p="abcgooglrcabac";  
    int len=strlen(p);  
    int max=getMaxHuiWenChar2(p,len);  
    cout<<endl;  
    cout<<max<<endl;  
    return 0;  
}  

 

 

 

posted @ 2012-10-28 23:00  三更_雨  阅读(1000)  评论(0编辑  收藏  举报