最长回文字串

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

#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;
}

 

posted on 2014-07-30 15:17  晓O(∩_∩)O~  阅读(243)  评论(0编辑  收藏  举报