• 最大回文子串


    题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。
    比如输入字符串“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;  
    }  

     

     

  • 相关阅读:
    Daily Recording 2020/01/09(关键词:1月01版,RouterScan)
    SQL语句技巧(转)
    实施的WinForms键盘快捷键方法
    日常问题汇总(1) 分组筛选
    设计模式 创建型设计模式
    TSQL查询逻辑查询处理
    无法嵌入互操作类型错误处理
    设计模式 创建模式
    设计模式 结构模式
    设计模式 行为模式
  • 原文地址:https://www.cnblogs.com/cyttina/p/2744015.html
Copyright © 2020-2023  润新知