Hdu_3068 Manacger算法的心得
生活随笔
收集整理的這篇文章主要介紹了
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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python中操作MySQL/Oracl
- 下一篇: MSSS攝影大賽計劃書(第三版)