Manacher算法--O(n)回文子串算法

来源:互联网 发布:杀破狼js 无损 编辑:程序博客网 时间:2024/06/03 22:35

马拉车算法详解地址

#include<cstring>#include<cstdio>#include<iostream>#include<algorithm>using namespace std;int p[2000010];//记录以s[i]为中心的回文串最大可向右延伸几位,p[i]-1为原串以i为中心的最长回文串长度int Find(string s){    int mx=0,id=0;//mx记录向右延伸到的最大值,id记录最长回文串的中心下标    memset(p,0,sizeof(p));    int l=s.size();    for(int i=1; i<l; i++)    {        if(mx>i)            p[i]=min(p[2*id-i],mx-i);//j=2*id-i ;   id为i与j的对称点,当mx-i>p[j],i会延伸到和j一样,反之会延伸到和mx-i一样        else            p[i]=1;        while(s[i-p[i]]==s[i+p[i]])//一个一个往后匹配相同长度加1            p[i]++;        if(i+p[i]>mx)//更新mx和id        {            mx=i+p[i];            id=i;        }    }    for(int i=0; i<l; i++)        if(i+p[i]==l)//找到可延伸到原串最后的最长回文串,返回长度            return p[i]-1;}int main(){    int ncase,Z=0;    scanf("%d",&ncase);    while(ncase--)    {        string str,x;        x+='$';//防止while判断越界        x+='#';        cin>>str;        int l=str.size();        for(int i=0; i<l; i++)//解决奇偶回文串,全变为奇数        {            x+=str[i];            x+='#';        }        //如果用char记得在最后加反斜杠0        printf("Case %d: %d\n",++Z,l-Find(x)+l);//差值为需要加多少达到回文串,加长度为加之后的回文串长度    }}
原创粉丝点击