关于manacher算法求字符串中最长字符串和其长度

来源:互联网 发布:sql select 多表查询 编辑:程序博客网 时间:2024/06/05 22:54
#include <iostream>using namespace std;/*  函数名:getmin  函数作用:获取较小值  函数参数:int a,int b  返回值:返回值int型的较小值 */int getmin(int a,int b){return a > b ? b : a;}/*  函数名:turn  函数作用:把给的字符数组转化成manacher的数组  函数参数:char Sh[]  返回值:返回manacher数组 */char* turn(char Sh[]){int size = 2 * strlen(Sh)+3;//'\0',$char *St = new char[size*sizeof(char)];    int i;    St[0] = '$';    for (i = 1; i < size;i+=2)    {       St[i] = '#';    }    for (i = 2;i < size;i+=2)    {    St[i] = Sh[i/2-1];    }    St[size-1] = '\0';    return St;     }/*  函数名:getmax  函数作用:获取回文串长度最大值  函数参数:int Pt[],int n  返回值:最大回文串长度 */int getmax(int Pt[],int n){   int i;int max = 0;for (i = 0;i < n;i++){if (max < Pt[i]){max = Pt[i];}}return max;}/*  函数名:manaher  函数作用:获取Pt[]每个i值的最大回文串长度  函数参数:char St[],char Pt[],int n  返回值:无 */char* manaher(char St[],int Pt[],int n)//n为St数组的长度{       char *record = new char[n];Pt[0] = 1;//mx是最大回文串的边界,id是最大的回文串的中心位置int mx,i,id;mx = 0;for (i = 1;i < n;i++){if (mx > i)//说明i的位置在最大回文串内{          Pt[i] = getmin(Pt[2*id-i],mx-i);//获取以i为中心在最大回文串的最小对称距离值}else//说明i的位置不在最大回文串内则无法确定初始的Pt[i]值于是赋值自身的1初始值{           Pt[i] = 1;}while (St[i+Pt[i]] == St[i-Pt[i]])//开始从i位置两侧扩散作比较是否相等来得出回文串的单侧边界值{Pt[i]++;}if (Pt[i]+i > mx){bzero(record,sizeof(record)); mx = Pt[i] + i;//更新最大回文串的边界id = i;//更新最大回文串的对称中心中心int j;int index = 2*id-mx+2;//找到回文串的第一个非'#'字符for (j = index;j < mx;j+=2)//+2找到每个非'#'字符{record[(j-index)/2] = St[j];}}}return record;}int main(int argc, char const *argv[]){char a[] = "12212321";char *St = turn(a);int n = strlen(St);int *Pt = new int[n];char *record = new char[n];record = manaher(St,Pt,n);    int i;    cout<<record<<endl;delete St;delete Pt;delete record;return 0;}

0 0
原创粉丝点击