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

此题参考


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;            //返回最长子串长度
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值