日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hdu_3068 Manacger算法的心得

發(fā)布時(shí)間:2024/10/8 编程问答 25 如意码农
生活随笔 收集整理的這篇文章主要介紹了 Hdu_3068 Manacger算法的心得 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

關(guān)于manacher算法,似乎在學(xué)完KMP之后,比較容易上手,雖然有些原理方面,我沒有理解的太深。

Manacher就是解決回文串的問題,求一個(gè)字符串中的最長(zhǎng)回文子串。

Manacher算法首先對(duì)字符串進(jìn)行處理:在所有字符之間插入‘#’,這樣的好處是,無論最長(zhǎng)回文子串是奇數(shù)個(gè)或者是偶數(shù)個(gè),都可以進(jìn)行處理。

處理過程是這樣的

假設(shè)原串是這樣的

1 2 3 4 5

a b b a d

處理完成一個(gè)新數(shù)組

0  1  2  3  4  5  6  7  8  9  10  11  12

? #  a #  b  #  b  #  a  #  d    #   0

1  2  1  2  5  2  1  2  1   2    1

首尾設(shè)置完全不相干的字符,是為了檢測(cè)回文時(shí),不會(huì)被算進(jìn)去。

最下一列叫做P[i] ,用來記錄當(dāng)前位的回文個(gè)數(shù),如果前后都不回文,默認(rèn)p[i]=1,(可以當(dāng)成自身回文)。

算法核心部分有三部分

還是直接用代碼來講吧:

HD#include <iostream>

#include <cstdio>
#include <cstring>
#define maxn 1100050
char str[maxn];
char a[maxn<<];
int p[maxn<<];
int min(int x,int y)
{
if (x<y) return x;
return y;
}
int main()
{while (scanf("%s",&str[]))
{ if (str[]=='E') break;
int i,j;
a[]='?',a[]='#';
for (i=; str[i]; i++)//處理成新的字符串。
{
a[(i<<)]=str[i];
a[(i<<)+]='#';
}
int n=(i<<);
a[n]=;
int maxid=,maxl=,id=;
for (i=; i<n; i++)//代碼的核心部分。
{
if (maxid>i)//如果之前記錄的最大回文覆蓋超過了當(dāng)前點(diǎn)坐標(biāo),進(jìn)行比較(這一步其實(shí)我也不是很理解,只知道可以節(jié)省搜索,優(yōu)化時(shí)間)
p[i]=min(p[*id-i],maxid-i); //進(jìn)行覆蓋度的比較,取較小的為p[i]
else
p[i]=; //否則直接定義為默認(rèn)值1。
while (a[i+p[i]]==a[i-p[i]]) p[i]++; //前后搜索,若回文,則+1;
ifmaxid)//獲取當(dāng)前最大覆蓋面,和覆蓋點(diǎn)。
{
maxid=p[i]+i;
id=i;
}
if (p[i]>maxl) maxl=p[i]; //最大回文長(zhǎng)度保存在p[i]中,取p[i]最大值即可。(此時(shí)最長(zhǎng)回文串的中間點(diǎn)即為i點(diǎn)(不過是加了‘#’的新串))
}
printf("%d\n",maxl-);
}
return ;
}

總結(jié)

以上是生活随笔為你收集整理的Hdu_3068 Manacger算法的心得的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。