manacher算法

用manacher算法,求最长回文字符串的长度

第一步:manacher算法,有一个巧妙的做法,就是讲奇偶串变成一个问题考虑。具体做法是,在原字符串的每个相邻两个字符中间插入一个分隔符,首尾也要插入字符,但首尾字符不能相同,以免在下面进行判断时,数组越界。(注意:插入的字符必须在原字符串中未出现过)

例:原串   acddcabsddsb(设为s串,长度为l)

转化后     ?#a#c#d#d#c#a#b#s#d#d#s#b(设为st串)

st[0]='?';s[1]='#';
for(int i=0;i<l;i++)
{
	st[2*i+2]=s[i];
	st[2*i+3]='#';
}
s[2*i+2]='\0';//此时st长度为L=2l+2;

第二步:判断st字符串中,以st[i]为中心元素的最长的回文字符串长度,即从st[i]向左右衍生进行判断;将结果存在一个数组中,如数组p[]中。

 

/*在i之前的元素中,分别以它们作为中心,找到一个得到的回文字符串右端点最大的元素,标记为id;
最大的右端点 标记为mx 
*/ 
int mx=0;id=0;
for(i=1;i<L;i++)
{
	if(mx>i)
	p[i]=p[id*2-i]<mx-i?p[id*2-i]:mx-i;
	else
	p[i]=1;
	while(st[i-p[i]]==st[i+p[i]])p[i]++;
	if(mx<p[i]+i)
	{
		mx=p[i]+i;
		id=i;
	}
}


第三步:输出原字符串中最长的回文字符串,这里用到了一个该算法的一个性质,即p[i]-1就是该回文字串在元字符串s中的长度;

int sum=0;
	   for(int i=1;i<L;i++)
       {
			sum=max(sum,p[i]);
	   }
		printf("%d\n",sum-1);




 

 

 

你可能感兴趣的:(manacher算法)