首页 > 代码库 > 最长回文字串理解(学习Manacher's algorithm)

最长回文字串理解(学习Manacher's algorithm)

关于字符串的子串问题,我们经常需要利用的是已经访问的部分的信息,来降低复杂度,和提高效率;在求最长回文子串的问题中,Manacher‘s algorithm提供了一种很好的机制,虽然部分地方不太容易理解

先说下核心的思想:先对原字符串进行预处理,将字符串"abc"转换为"$#a#b#c#"的形式,既避免了访问越界的问题,又保证每一个字符有至少一个对称的串(真字符,或是假的“#”)

         预留两对变量(当前得到的中心位置“center”,和字符串右侧最远位置“R”,以及对称的左侧“L”)(当前访问字符位置“i”,以及相对当前访问位置“center”的对称位置“i_")

#include <string.h>#include <stdio.h>#include <iostream>using namespace std;void preprocess(char str[],char result[]);int min(int a, int b);int p[2020];int main(){    int center,i,i_,L,R,j;    char str[1010],result[2020];    int maxlen, index,len;    cin.getline(str,1000,\n);    preprocess(str,result);    /*printf("%s",result);*/    //handle the string    center=0,R=0;    p[0]=0;    len = strlen(result);    //i from 1,so the begging position is placed ‘$‘ to avoid the segment error    for(i=1;i<len-1;i++){        i_=center*2-i;//the symmetric position        L=center*2-R;        p[i] = (R > i) ? min(R - i, p[i_]) : 0;        while (i + p[i] + 1<len&&result[i + p[i] + 1] == result[ i- p[i] - 1])            p[i]++;        //if R expands,then modify it        if (R - i <p[i]){            center = i;            R = i + p[i];        }    }    //find the maximum length in p    maxlen = 0, index = 0;    for (i = 0; i < strlen(result); i++){        if (maxlen < p[i]){            maxlen = p[i];            index = i;        }    }    printf("%d", maxlen);    return 0;}void preprocess(char str[],char result[]){    int len=strlen(str),i,j;    result[0]=$;//indicates the start     for(i=0,j=1;i<len;i++){        result[j++]=#;        result[j++]=str[i];    }    result[j]=#;    result[j+1]=\0;}int min(int a, int b){    if (a < b)        return a;    else        return b;}

p[i]记录的是位置i处的字符的右侧对称长度(包括str[i]自身),最关键的是理解这几句:

 p[i] = (R > i) ? min(R - i, p[i_]) : 0;        while (i + p[i] + 1<len&&result[i + p[i] + 1] == result[ i- p[i] - 1])            p[i]++;        //if R expands,then modify it        if (R - i <p[i]){            center = i;            R = i + p[i];        }

最长回文字串理解(学习Manacher's algorithm)