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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

最小表示

發(fā)布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最小表示 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?

字符串最小表示法 O(n)算法

?6869人閱讀?評論(5)?收藏?舉報

網(wǎng)上看了這篇文章后還是感覺有些地方講的沒有詳細(xì)的證明所以添加了一點(diǎn) 紅色字是博主寫的

求字符串的循環(huán)最小表示:

?

上面說的兩個字符串同構(gòu)的,并沒有直接先求出Min(s),而是通過指針移動,當(dāng)某次匹配串長時,那個位置就是Min(s)。而這里的問題就是:不是給定兩個串,而是給出一個串,求它的Min(s),eg:Min(“babba”) = 4。那么由于這里并非要求兩個串的同構(gòu),而是直接求它的最小表示,由于源串和目標(biāo)串相同,所以處理起來既容易又需要有一些變化:我們?nèi)匀辉O(shè)置兩個指針,i, j,其中i指向0,j指向1,仍然采用上面的滑動方式:

?

(1)? 利用兩個指針i, j。初始化時i指向0, j指向1。

?

(2)? k = 0開始,檢驗s[i+k] 與 s[j+k] 對應(yīng)的字符是否相等,如果相等則k++,一直下去,直到找到第一個不同,(若k試了一個字符串的長度也沒找到不同,則那個位置就是最小表示位置,算法終止并返回)。則該過程中,s[i+k] 與 s[j+k]的大小關(guān)系,有三種情況:

? 證明的時候假設(shè)(i<j)的,無傷大雅 ;

???? (A). s[i+k] > s[j+k],則i滑動到i+k+1處 --- 即s1[i->i+k]不會是該循環(huán)字符串的“最小表示”的前綴。

?證明如下

? ??

???? (B). s[i+k] < s[j+k],則j滑動到j(luò)+k+1處,原因同上。

?證明如下


???? (C). s[i+k] = s[j+k],則 k++; if (k == len) 返回結(jié)果。?

??? 注:這里滑動方式有個小細(xì)節(jié),若滑動后i == j,將正在變化的那個指針再+1。直到p1、p2把整個字符串都檢驗完畢,返回兩者中小于 len 的值。

?

(3)?? 如果 k == len, 則返回i與j中的最小值

?

????? 如果 i >= len?? 則返回j

?

????? 如果 j >= len?? 則返回i

如果看了上一篇文章 很容易對這里的i,j 產(chǎn)生誤會 ?誤以為i為ans,j為比較指針

實際上這題中 i,j 都可能存有ans 兩者互相更新,直到有一個更新后超過了len(包括len) 的時候 另一個即為正解

(4)?? 進(jìn)一步的優(yōu)化,例如:i要移到i+k+1時,如果i+k+1 <= p2的話,可以直接把i移到 j+1,因為,j到j(luò)+k已經(jīng)檢驗過了該前綴比以i到i+k之間任何一個位前綴都小;j時的類似,移動到i+1。

?這個優(yōu)化就無需解釋了

至此,求一個字符串的循環(huán)最小表示在O(n)時間實現(xiàn),感謝大牛的論文。其中實現(xiàn)時的小細(xì)節(jié)“如果滑動后p1 == p2,將正在變化的那個指針再+1”,開始沒有考慮,害得我想了幾個小時都覺得無法進(jìn)行正確的移動。具體例題有兩個:http://acm.zju.edu.cn 的2006和1729題。一個是10000規(guī)模一個是100000規(guī)模。運(yùn)行時間前者是0S,后者是0.05S。


[cpp]?view plaincopy
  1. int?MinimumRepresentation(int?*s,?int?l)????
  2. {????
  3. ? ?int i,j,k;
    ? ? i=0;j=1;k=0;
    ? ? while(i<l&&j<l&&k<l)
    ? ? {
    ? ? ? ? int t=s[(i+k)%l]-s[(j+k)%l];
    ? ? ? ? if(!t)
    ? ? ? ? ? ? k++;
    ? ? ? ? else
    ? ? ? ? {
    ? ? ? ? ? ? if(t>0)
    ? ? ? ? ? ? i=i+k+1;
    ? ? ? ? ? ? else
    ? ? ? ? ? ? j=j+k+1;
    ? ? ? ? ? ? if(i==j)
    ? ? ? ? ? ? ? ? j++;
    ? ? ? ? ? ? k=0;
    ? ? ? ? }
    ? ? }
    ? ? return i>j?j:i;
  4. }???

總結(jié)

以上是生活随笔為你收集整理的最小表示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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