您的位置:首页 > 其它

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

2016-04-28 14:44 344 查看
#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
;
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
;
char *record = new char
;
record = manaher(St,Pt,n);
int i;
cout<<record<<endl;
delete St;
delete Pt;
delete record;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: