您的位置:首页 > 其它

字符串中最长的回文子串问题

2015-04-21 16:33 316 查看
此题参考

Manache算法,网上很多网友都说需要在转换后的字符串(即是在字符串中添加了‘#’)的最前面加上一个额外的字符,但是我觉得没有必要这么做: 最初的时候我选择第二个字符作为mid 然后寻找后面是否有更适合做mid的字符,如果有则替换。

具体代码实现如下:

#include <stdio.h>

#include <string.h>

#define MIN(a,b) ((a)>(b)?(b):(a))

void FullStr(char*res,char*des);

int FindMaxLen(char*res,int Len);

int main()

{

char Res[1000],Des[1000];

while (scanf("%s",Res)!=EOF)

{

FullStr(Res,Des);

printf("%d\n",FindMaxLen(Des,strlen(Des)));

}

return 0;

}

//讲原字符串中添加上‘#’使得奇数和偶数个字符可以按照相同的方式处理。

void FullStr(char*res,char*des)

{

int j=0;

for (int i=0;res[i]!='\0';i++)

{

des[j++]='#';

des[j++]=res[i];

}

des[j++]='#';

des[j]='\0';

}

//寻找最大的回文子串的长度

int FindMaxLen(char*res,int Len)

{

int P[2000]={0};

int max=2; //max代表最右边的最长子串的下标

int id=1; //最初的时候选择第二个字符作为最长子串的中间字符

P[0]=1;

P[1]=2;

for (int i=2;i<Len;i++)

{

if (max>i)

{

P[i]=MIN(max-i,P[2*id-i]); // 如果i在已有的最长子串的范围内,则比较i的对称点和i距离最长子串最右边的距离,选择较小者

}

else

{

P[i]=1;

}

while (i+P[i]<Len && i-P[i]>=0 && res[i+P[i]]==res[i-P[i]]) // i为中心向两边扩展

{

P[i]++;

}

if (P[i]>max-id+1) //如果作为中心的子串长度大于id为中心的子串长度,则替换id和max

{

id=i;

max=id+P[i]-1;

}

}

return max-id; //返回最长子串长度

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐