青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

The Fourth Dimension Space

枯葉北風寒,忽然年以殘,念往昔,語默心酸。二十光陰無一物,韶光賤,寐難安; 不畏形影單,道途阻且慢,哪曲折,如渡飛湍。斬浪劈波酬壯志,同把酒,共言歡! -如夢令

KMP算法詳解(轉自 matrix67)

如果機房馬上要關門了,或者你急著要和MM約會,請直接跳到第六個自然段。

    我們這里說的KMP不是拿來放電影的(雖然我很喜歡這個軟件),而是一種算法。KMP算法是拿來處理字符串匹配的。換句話說,給你兩個字符串,你需要回答,B串是否是A串的子串(A串是否包含B串)。比如,字符串A="I'm matrix67",字符串B="matrix",我們就說B是A的子串。你可以委婉地問你的MM:“假如你要向你喜歡的人表白的話,我的名字是你的告白語中的子串嗎?”
    解決這類問題,通常我們的方法是枚舉從A串的什么位置起開始與B匹配,然后驗證是否匹配。假如A串長度為n,B串長度為m,那么這種方法的復雜度是O (mn)的。雖然很多時候復雜度達不到mn(驗證時只看頭一兩個字母就發現不匹配了),但我們有許多“最壞情況”,比如,A= "aaaaaaaaaaaaaaaaaaaaaaaaaab",B="aaaaaaaab"。我們將介紹的是一種最壞情況下O(n)的算法(這里假設 m<=n),即傳說中的KMP算法。
    之所以叫做KMP,是因為這個算法是由Knuth、Morris、Pratt三個提出來的,取了這三個人的名字的頭一個字母。這時,或許你突然明白了AVL 樹為什么叫AVL,或者Bellman-Ford為什么中間是一杠不是一個點。有時一個東西有七八個人研究過,那怎么命名呢?通常這個東西干脆就不用人名字命名了,免得發生爭議,比如“3x+1問題”。扯遠了。
    個人認為KMP是最沒有必要講的東西,因為這個東西網上能找到很多資料。但網上的講法基本上都涉及到“移動(shift)”、“Next函數”等概念,這非常容易產生誤解(至少一年半前我看這些資料學習KMP時就沒搞清楚)。在這里,我換一種方法來解釋KMP算法。

    假如,A="abababaababacb",B="ababacb",我們來看看KMP是怎么工作的。我們用兩個指針i和j分別表示,A[i-j+ 1..i]與B[1..j]完全相等。也就是說,i是不斷增加的,隨著i的增加j相應地變化,且j滿足以A[i]結尾的長度為j的字符串正好匹配B串的前 j個字符(j當然越大越好),現在需要檢驗A[i+1]和B[j+1]的關系。當A[i+1]=B[j+1]時,i和j各加一;什么時候j=m了,我們就說B是A的子串(B串已經整完了),并且可以根據這時的i值算出匹配的位置。當A[i+1]<>B[j+1],KMP的策略是調整j的位置(減小j值)使得A[i-j+1..i]與B[1..j]保持匹配且新的B[j+1]恰好與A[i+1]匹配(從而使得i和j能繼續增加)。我們看一看當 i=j=5時的情況。

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B = a b a b a c b
    j = 1 2 3 4 5 6 7


    此時,A[6]<>B[6]。這表明,此時j不能等于5了,我們要把j改成比它小的值j'。j'可能是多少呢?仔細想一下,我們發現,j'必須要使得B[1..j]中的頭j'個字母和末j'個字母完全相等(這樣j變成了j'后才能繼續保持i和j的性質)。這個j'當然要越大越好。在這里,B [1..5]="ababa",頭3個字母和末3個字母都是"aba"。而當新的j為3時,A[6]恰好和B[4]相等。于是,i變成了6,而j則變成了 4:

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B =     a b a b a c b
    j =     1 2 3 4 5 6 7


    從上面的這個例子,我們可以看到,新的j可以取多少與i無關,只與B串有關。我們完全可以預處理出這樣一個數組P[j],表示當匹配到B數組的第j個字母而第j+1個字母不能匹配了時,新的j最大是多少。P[j]應該是所有滿足B[1..P[j]]=B[j-P[j]+1..j]的最大值。
    再后來,A[7]=B[5],i和j又各增加1。這時,又出現了A[i+1]<>B[j+1]的情況:

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B =     a b a b a c b
    j =     1 2 3 4 5 6 7


    由于P[5]=3,因此新的j=3:

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B =         a b a b a c b
    j =         1 2 3 4 5 6 7


    這時,新的j=3仍然不能滿足A[i+1]=B[j+1],此時我們再次減小j值,將j再次更新為P[3]:

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B =             a b a b a c b
    j =             1 2 3 4 5 6 7


    現在,i還是7,j已經變成1了。而此時A[8]居然仍然不等于B[j+1]。這樣,j必須減小到P[1],即0:

    i = 1 2 3 4 5 6 7 8 9 ……
    A = a b a b a b a a b a b …
    B =               a b a b a c b
    j =             0 1 2 3 4 5 6 7


    終于,A[8]=B[1],i變為8,j為1。事實上,有可能j到了0仍然不能滿足A[i+1]=B[j+1](比如A[8]="d"時)。因此,準確的說法是,當j=0了時,我們增加i值但忽略j直到出現A[i]=B[1]為止。
    這個過程的代碼很短(真的很短),我們在這里給出:

j:=0;
for i:=1 to n do
begin
   while (j>0) and (B[j+1]<>A[i]) do j:=P[j];
   if B[j+1]=A[i] then j:=j+1;
   if j=m then
   begin
      writeln('Pattern occurs with shift ',i-m);
      j:=P[j];
   end;
end;


    最后的j:=P[j]是為了讓程序繼續做下去,因為我們有可能找到多處匹配。
    這個程序或許比想像中的要簡單,因為對于i值的不斷增加,代碼用的是for循環。因此,這個代碼可以這樣形象地理解:掃描字符串A,并更新可以匹配到B的什么位置。

    現在,我們還遺留了兩個重要的問題:一,為什么這個程序是線性的;二,如何快速預處理P數組。
    為什么這個程序是O(n)的?其實,主要的爭議在于,while循環使得執行次數出現了不確定因素。我們將用到時間復雜度的攤還分析中的主要策略,簡單地說就是通過觀察某一個變量或函數值的變化來對零散的、雜亂的、不規則的執行次數進行累計。KMP的時間復雜度分析可謂攤還分析的典型。我們從上述程序的j 值入手。每一次執行while循環都會使j減?。ǖ荒軠p成負的),而另外的改變j值的地方只有第五行。每次執行了這一行,j都只能加1;因此,整個過程中j最多加了n個1。于是,j最多只有n次減小的機會(j值減小的次數當然不能超過n,因為j永遠是非負整數)。這告訴我們,while循環總共最多執行了n次。按照攤還分析的說法,平攤到每次for循環中后,一次for循環的復雜度為O(1)。整個過程顯然是O(n)的。這樣的分析對于后面P數組預處理的過程同樣有效,同樣可以得到預處理過程的復雜度為O(m)。
    預處理不需要按照P的定義寫成O(m^2)甚至O(m^3)的。我們可以通過P[1],P[2],...,P[j-1]的值來獲得P[j]的值。對于剛才的B="ababacb",假如我們已經求出了P[1],P[2],P[3]和P[4],看看我們應該怎么求出P[5]和P[6]。P[4]=2,那么P [5]顯然等于P[4]+1,因為由P[4]可以知道,B[1,2]已經和B[3,4]相等了,現在又有B[3]=B[5],所以P[5]可以由P[4] 后面加一個字符得到。P[6]也等于P[5]+1嗎?顯然不是,因為B[ P[5]+1 ]<>B[6]。那么,我們要考慮“退一步”了。我們考慮P[6]是否有可能由P[5]的情況所包含的子串得到,即是否P[6]=P[ P[5] ]+1。這里想不通的話可以仔細看一下:

        1 2 3 4 5 6 7
    B = a b a b a c b
    P = 0 0 1 2 3 ?


    P[5]=3是因為B[1..3]和B[3..5]都是"aba";而P[3]=1則告訴我們,B[1]、B[3]和B[5]都是"a"。既然P[6]不能由P[5]得到,或許可以由P[3]得到(如果B[2]恰好和B[6]相等的話,P[6]就等于P[3]+1了)。顯然,P[6]也不能通過P[3]得到,因為B[2]<>B[6]。事實上,這樣一直推到P[1]也不行,最后,我們得到,P[6]=0。
    怎么這個預處理過程跟前面的KMP主程序這么像呢?其實,KMP的預處理本身就是一個B串“自我匹配”的過程。它的代碼和上面的代碼神似:

P[1]:=0;
j:=0;
for i:=2 to m do
begin
   while (j>0) and (B[j+1]<>B[i]) do j:=P[j];
   if B[j+1]=B[i] then j:=j+1;
   P[i]:=j;
end;


    最后補充一點:由于KMP算法只預處理B串,因此這種算法很適合這樣的問題:給定一個B串和一群不同的A串,問B是哪些A串的子串。

    串匹配是一個很有研究價值的問題。事實上,我們還有后綴樹,自動機等很多方法,這些算法都巧妙地運用了預處理,從而可以在線性的時間里解決字符串的匹配。我們以后來說。

    昨天發現一個特別暈的事,知道怎么去掉BitComet的廣告嗎?把界面語言設成英文就行了。
    還有,金山詞霸和Dr.eye都可以去自殺了,Babylon素王道。

來自:http://www.matrix67.com/blog/archives/115

posted on 2009-07-31 12:25 abilitytao 閱讀(283) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久久久久综合日本| 欧美福利电影网| 国产婷婷精品| 国产精品国产一区二区| 欧美性猛片xxxx免费看久爱| 最近看过的日韩成人| 久久精品夜色噜噜亚洲a∨ | 9人人澡人人爽人人精品| 亚洲激情国产精品| 夜夜嗨av一区二区三区网页| 亚洲影院色无极综合| 午夜影视日本亚洲欧洲精品| 久久久久久欧美| 欧美激情精品久久久久久| 亚洲激情国产精品| 亚洲一区二区三区精品在线 | 另类天堂av| 亚洲人成网站色ww在线| 一区二区欧美视频| 久久成人综合视频| 欧美日韩1区2区3区| 国产日韩精品综合网站| 亚洲国产欧美久久| 亚洲尤物在线| 噜噜噜91成人网| 亚洲精品久久嫩草网站秘色| 午夜精品福利视频| 欧美韩日一区二区| 国产欧美一区二区白浆黑人| 亚洲精品欧美精品| 久久久久久精| 洋洋av久久久久久久一区| 欧美伊人久久大香线蕉综合69| 久久夜色精品国产欧美乱| 米奇777超碰欧美日韩亚洲| 亚洲福利视频专区| 亚洲一区区二区| 免费成人av资源网| 国产日韩欧美不卡在线| 亚洲一区二区免费在线| 欧美成人中文字幕| 性欧美大战久久久久久久免费观看| 欧美激情第10页| 在线观看一区二区精品视频| 性欧美在线看片a免费观看| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲视频一区二区| 亚洲高清不卡| 久久久一区二区| 国产伪娘ts一区| 香蕉久久一区二区不卡无毒影院| 亚洲欧洲日本在线| 欧美成人免费全部观看天天性色| 国产欧美一区二区精品性色| 亚洲欧美激情精品一区二区| 日韩一级黄色av| 欧美日韩一区二区三区在线看 | 久久影院亚洲| 黄色精品一二区| 久久精品国产免费看久久精品| 在线一区二区三区做爰视频网站| 欧美日韩一区二区三区四区在线观看| 日韩亚洲欧美综合| 日韩视频在线一区二区| 欧美日韩国产欧美日美国产精品| 日韩午夜免费| 一本大道久久a久久精二百| 欧美午夜理伦三级在线观看| 亚洲一级在线观看| 一区二区三区导航| 国产精品免费aⅴ片在线观看| 亚洲综合视频网| 午夜精品三级视频福利| 韩国一区二区在线观看| 欧美成人综合| 欧美日韩亚洲综合| 亚洲校园激情| 午夜免费久久久久| 樱桃国产成人精品视频| 欧美激情一区二区三区全黄| 欧美乱在线观看| 午夜视频一区在线观看| 久久精品国产亚洲a| 亚洲精品小视频| 亚洲免费一级电影| 在线看片第一页欧美| 最新国产成人av网站网址麻豆| 欧美视频在线观看| 久久成人免费网| 欧美精品www在线观看| 午夜精品成人在线| 久久综合九色欧美综合狠狠| 亚洲一区二区欧美| 久久久久综合一区二区三区| 亚洲精品国产精品国自产观看| 9人人澡人人爽人人精品| 狠狠色伊人亚洲综合成人| 亚洲日本欧美日韩高观看| 国产亚洲日本欧美韩国| 亚洲精品综合精品自拍| 国产一区二区三区自拍| 亚洲国产精品久久久久久女王| 国产精品美女久久| 欧美激情精品久久久久| 国产精品入口夜色视频大尺度 | 久久激情网站| 亚洲午夜一区二区三区| 久久国产黑丝| 亚洲一区精品视频| 麻豆成人91精品二区三区| 亚洲欧美激情诱惑| 欧美黄色免费| 麻豆精品一区二区综合av| 欧美香蕉视频| 亚洲电影在线免费观看| 韩国av一区二区三区| 亚洲午夜国产成人av电影男同| 亚洲欧洲免费视频| 久久久国产亚洲精品| 亚洲欧美一区二区三区在线| 欧美日本免费| 亚洲国产天堂网精品网站| 激情成人中文字幕| 午夜精品久久久久| 亚洲一线二线三线久久久| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美日韩一二区| 欧美11—12娇小xxxx| 国产亚洲在线| 亚洲欧美视频一区二区三区| 亚洲午夜成aⅴ人片| 欧美日韩91| 亚洲精品日韩在线观看| 91久久在线视频| 久久午夜色播影院免费高清| 久久久爽爽爽美女图片| 国产视频久久网| 午夜视频一区| 午夜性色一区二区三区免费视频 | 国产精品麻豆欧美日韩ww| 亚洲精品视频免费| 日韩视频在线一区二区三区| 欧美国产高清| 亚洲人成在线影院| 一区二区三区日韩精品| 欧美午夜精品久久久久久孕妇 | 噜噜噜91成人网| 欧美大胆a视频| 99riav1国产精品视频| 欧美理论在线播放| 一本大道久久精品懂色aⅴ | 久久激情久久| 在线观看三级视频欧美| 久久久免费观看视频| 免费在线看成人av| 亚洲国产高清一区二区三区| 欧美gay视频激情| 亚洲毛片网站| 欧美在线日韩在线| 在线免费一区三区| 欧美日韩精品免费观看| 国产精品99久久久久久久女警| 欧美亚洲一区二区三区| 好吊成人免视频| 欧美伦理a级免费电影| 这里只有精品在线播放| 久久人人爽国产| 一区二区三区导航| 国产三级精品在线不卡| 欧美成人综合网站| 午夜精品久久久久久久99樱桃 | 国产精品麻豆成人av电影艾秋| 欧美伊人久久| 亚洲精品久久久久久一区二区| 亚洲欧美在线磁力| 91久久综合| 国语自产偷拍精品视频偷 | 久久久久久久网| 日韩一级在线| 韩国一区二区三区在线观看| 欧美少妇一区二区| 久久久久成人精品| 一个色综合av| 欧美中文在线观看国产| 91久久在线播放| 国产日韩欧美不卡在线| 欧美激情中文字幕乱码免费| 新67194成人永久网站| 亚洲精品国产精品国自产在线 | 亚洲视频高清| 一区二区在线观看视频在线观看 | 欧美日韩在线视频首页| 久久婷婷激情| 性欧美xxxx视频在线观看| 亚洲最黄网站| 亚洲人成人77777线观看| 裸体素人女欧美日韩| 欧美在线一二三四区| 一本一本久久a久久精品综合麻豆| 国产日韩欧美日韩大片|