最长回文字串-manacher算法

来源:互联网 发布:2017最新seo 编辑:程序博客网 时间:2024/06/05 11:41

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>


using namespace std;
const int MaxSize = 1001;
#define min(a, b) ((a) < (b) ?(a) : (b));


void Manacher(char *str,int *p)
{
    int id;
    int mx = 0;
    int len = strlen(str);
    for(int i = 0;i < len;i++)
    {
        if(mx > i)
        {
            p[i] = min(p[2 * id - i],p[mx - i]);
        }


        else
        {
            p[i] = 1;
        }


        for(;(str[p[i] + i] == str[p[i] - i]);p[i]++);
        if(p[i] + i > mx)
        {
            mx = p[i] + i;
            id = i;
        }
    }
}


注:


if(mx > i) p[i]= min(p[2 * id - i], mx -i);
这是代码中最核心的一句话,它的作用是让我们在以i为中心向左右扩展时,尽量减少重复的比较,当mx > i 时会有两种情况。设j = 2 *id – i  以id为中心i的对称位置。
第一:当以i为中心的回文和以j为中心的回文都在以id为中心的回文中时。
 由于回文的对称性,这时p[i]最小为p[j] 这是表达式前半部分。
第二:当以i为中心的回文或以j为中心的回文不在以id为中心的回文中时。
        q a b a c a b a c
             j   id   i
或:
c a b a c a b q c
    j  id   i
这时以i为中心的最长回文不一定大于p[i],但是由于回文的对称性,他最小是mx-i(p[j]大时)或p[j]。
0 0
原创粉丝点击