P1210 回文检测 (manacher算法)

P1210 回文检测 (manacher算法)


#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define N 20010
char newn[2*N];
char str1[N];
char str2[N];
int  pos[N];
int  pos2[2*N];
int  Len[2*N];
int  cnt1,cnt2;
int  init(char str[])
{
    int i;
    newn[0]='$';
    newn[1]='#';
    int j=2;
    for(i=0;i<cnt2;i++)
    {
        newn[j]=str2[i];
        pos2[j]=pos[i]; //因为要用到新的数组了,所以用pos2记录在新数组中ABC在原来数组中的位置
        j++;
        newn[j++]='#';
    }
    newn[j]='\0';
    return j;
}
int main()
{
     int  left,right;
     int len,i=0,j=0;
     int maxn=0,ans=0,po=0,maxlen=-1;
     while((str1[i]=getchar())!=EOF)
     i++;
     cnt1=i;
    for(i=0;i<cnt1;i++)
    {
      if((str1[i]<='z'&&str1[i]>='a')||(str1[i]<='Z'&&str1[i]>='A'))//str2只取ABC字母
      {
          str2[j]=str1[i];
          pos[j]=i;  //pos[j]是只记录ABC字母的位置。因为起点与终点一定是ABC字符啊,所以有其他字符在其中间,只要知道开头结尾就行
          j++;
      }
    }
    cnt2=j;
    for(i=0;i<cnt2;i++)
    if(str2[i]<='Z'&&str2[i]>='A')
    str2[i]=str2[i]-'A'+'a';  //str2只取小写字母,因为,回文大小写都算,但字符判断确不是这样,所以这样处理
    len=init(str2);        //init是要返回新数组长度的。
    for(i=1;i<len;i++)
    {
            if(maxn>i)
            Len[i]=min(maxn-i,Len[2*po-i]);
            else
            Len[i]=1;
            while(newn[i-Len[i]]==newn[i+Len[i]])//i+-Len[i]
            Len[i]++;
            if(Len[i]+i>maxn)
            {
                maxn=Len[i]+i;
                po=i;
            }
            if(maxlen<Len[i]-1)
            {


                maxlen=Len[i]-1;
                left=i-Len[i]+2; //left,刚好是左边界,不算’#‘这个的
                right=i+Len[i]-2;//left.right是相对新数组而言的。
            }
            ans=max(ans,Len[i]);
     }
        printf("%d\n",ans-1);
        for(i=pos2[left];i<=pos2[right];i++)//这里i是取等号。
        printf("%c",str1[i]);
        printf("\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值