• 最长回文字串


    研究了一下便于记忆的两种回文字串方法,代码如下:

    #include <iostream>
    #include <string>
    using namespace std;
    //最大回文字串,有如下方法:
    //http://blog.csdn.net/linulysses/article/details/5634104
    //动态规划法
    /*
    xPy肯定不是回文,xPx是回文当且仅当P是回文,如下算法使用LP[i][j]表示aiai+1...aj是否是回文
    LP[i][j]=true  i>=j时候表示单个字符串
    LP[i][j]=true  i<j当且仅当LP[i+1][j-1]=true且S[i]=S[j]
    否则 LP[i][j]=false
    
    首先对于 长度进行 1-len 的循环
    然后对于每个回文的起点i 再根据不同的长度做调整
    o(n^2)
    */
    string max_huiwen_dynamic(string s){
        string huiwen;
        int len=s.length(),i,j,k,h_start=0,h_end=0;
        if(len<=0) return huiwen; 
        bool **_LP=(bool**)malloc(sizeof(bool*)*len);
    
        for (i=0;i<len;i++)
        {
            _LP[i]=(bool*)malloc(sizeof(bool)*len);
            _LP[i][i]=true;
        }
        for (i=1;i<=len;i++)//长度循环
        {        
            for (j=0;j<len-i;j++)
            {
                k=i+j-1;
                if(i==j||(s[k]==s[j]&&_LP[j+1][k-1])){
                    _LP[j][k]=true;
                    if(h_end-h_start<i){
                        h_end=k+1;
                        h_start=j;
                    }
                } else _LP[j][k]=false;
            }
        }
        huiwen.assign(s.begin()+h_start,s.begin()+h_end);
        return huiwen;
    }
    
    //Manacher算法
    //http://www.cnblogs.com/houkai/p/3371807.html
    //利用先前计算好的一个保存以每个字符为中心点坐标的回文的长度,假设当前计算的点在回文区间内,则只需要查看是否和另一侧的相同即可。
    //具有记忆性
    string padding(string str)
    {
        string tStr;
        int len=str.length();
        tStr.push_back('$');
        for(int i=0;i<len;i++){
            tStr.push_back('#');
            tStr.push_back(str[i]);
        }
        tStr.push_back('#');
        return tStr;
    }
    string Manacher(string s)
    {
        string tStr=padding(s),returnStr;
        int mx=0,pi=1,len=tStr.length();
        //辅助数组
        int*p=new int[len];
        memset(p,0,sizeof(int)*len);
        for (int i=0;i<len;i++)
        {
            if(mx>i) p[i]=min(mx-i,p[2*pi-i]);
            else p[i]=1;
    
            while(i-p[i]>0&&i+p[i]<len&&tStr[i-p[i]]==tStr[i+p[i]]) p[i]++;
    
            if(i+p[i]>mx){
                mx=p[i]+i;
                pi=i;
            }
        }
        int maxLen=0,pos=0;
        for (int i=0;i<len;i++)
        {
            if(maxLen<p[i]){
                maxLen=p[i];
                pos=i;
            }
        }
        //现在字符串位置pos/2 ,移动长度(maxlen-1)/2
        returnStr.assign(s.begin()+(pos-maxLen)/2,s.begin()+(pos-maxLen)/2+maxLen-1);
        return returnStr;
    }
  • 相关阅读:
    vue中computed计算属性和methods区别
    java解决跨域问题
    redis服务端开启
    使用excel生成商品条形码
    MySQL主键自增时SQL写法/当前时间写法
    修改MySQL数据库密码
    MySQL5.6.42解压版安装教程
    完全卸载MySQL数据库
    IDEA快捷键及xml文件中网址报错
    IDEA导入外部包
  • 原文地址:https://www.cnblogs.com/havePassed/p/3878133.html
Copyright © 2020-2023  润新知