欧美网址在线观看-亚洲最新毛片-国产成人免费爽爽爽视频-亚洲一区在线影院-日韩欧美在线观看视频网站-男女激情四射-成人一区二区免费看-欧美亚洲综合在线-日韩一级视频在线播放-国产成人三级视频在线播放-亚洲中文字幕日产无码2020-99久久久国产精品免费无卡顿-av在线观看地址-果冻传媒mv免费播放在线观看-欧美在线观看视频免费-日韩天天操

聯(lián)系我們 - 廣告服務(wù) - 聯(lián)系電話:
您的當(dāng)前位置: > 關(guān)注 > > 正文

KMP算法是什么?KMP算法詳解

來源:CSDN 時間:2023-01-16 08:07:13


(資料圖)

KMP算法詳解

如果機房馬上要關(guān)門了,或者你急著要和MM約會,請直接跳到第六個自然段。     我們這里說的KMP不是拿來放電影的(雖然我很喜歡這個軟件),而是一種算法。KMP算法是拿來處理字符串匹配的。換句話說,給你兩個字符串,你需要回答,B串是否是A串的子串(A串是否包含B串)。比如,字符串A="I"m matrix67",字符串B="matrix",我們就說B是A的子串。你可以委婉地問你的MM:“假如你要向你喜歡的人表白的話,我的名字是你的告白語中的子串嗎?”     解決這類問題,通常我們的方法是枚舉從A串的什么位置起開始與B匹配,然后驗證是否匹配。假如A串長度為n,B串長度為m,那么這種方法的復(fù)雜度是O (mn)的。雖然很多時候復(fù)雜度達不到mn(驗證時只看頭一兩個字母就發(fā)現(xiàn)不匹配了),但我們有許多“最壞情況”,比如,A= "aaaaaaaaaaaaaaaaaaaaaaaaaab",B="aaaaaaaab"。我們將介紹的是一種最壞情況下O(n)的算法(這里假設(shè) m<=n),即傳說中的KMP算法。     之所以叫做KMP,是因為這個算法是由Knuth、Morris、Pratt三個提出來的,取了這三個人的名字的頭一個字母。這時,或許你突然明白了AVL 樹為什么叫AVL,或者Bellman-Ford為什么中間是一杠不是一個點。有時一個東西有七八個人研究過,那怎么命名呢?通常這個東西干脆就不用人名字命名了,免得發(fā)生爭議,比如“3x+1問題”。扯遠了。     個人認(rèn)為KMP是最沒有必要講的東西,因為這個東西網(wǎng)上能找到很多資料。但網(wǎng)上的講法基本上都涉及到“移動(shift)”、“Next函數(shù)”等概念,這非常容易產(chǎn)生誤解(至少一年半前我看這些資料學(xué)習(xí)KMP時就沒搞清楚)。在這里,我換一種方法來解釋KMP算法。     假如,A="abababaababacb",B="ababacb",我們來看看KMP是怎么工作的。我們用兩個指針i和j分別表示,A[i-j+ 1..i]與B[1..j]完全相等。也就是說,i是不斷增加的,隨著i的增加j相應(yīng)地變化,且j滿足以A[i]結(jié)尾的長度為j的字符串正好匹配B串的前 j個字符(j當(dāng)然越大越好),現(xiàn)在需要檢驗A[i+1]和B[j+1]的關(guān)系。當(dāng)A[i+1]=B[j+1]時,i和j各加一;什么時候j=m了,我們就說B是A的子串(B串已經(jīng)整完了),并且可以根據(jù)這時的i值算出匹配的位置。當(dāng)A[i+1]<>B[j+1],KMP的策略是調(diào)整j的位置(減小j值)使得A[i-j+1..i]與B[1..j]保持匹配且新的B[j+1]恰好與A[i+1]匹配(從而使得i和j能繼續(xù)增加)。我們看一看當(dāng) 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"可能是多少呢?仔細(xì)想一下,我們發(fā)現(xiàn),j"必須要使得B[1..j]中的頭j"個字母和末j"個字母完全相等(這樣j變成了j"后才能繼續(xù)保持i和j的性質(zhì))。這個j"當(dāng)然要越大越好。在這里,B [1..5]="ababa",頭3個字母和末3個字母都是"aba"。而當(dāng)新的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無關(guān),只與B串有關(guān)。我們完全可以預(yù)處理出這樣一個數(shù)組P[j],表示當(dāng)匹配到B數(shù)組的第j個字母而第j+1個字母不能匹配了時,新的j最大是多少。P[j]應(yīng)該是所有滿足B[1..P[j]]=B[j-P[j]+1..j]的最大值。     再后來,A[7]=B[5],i和j又各增加1。這時,又出現(xiàn)了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     現(xiàn)在,i還是7,j已經(jīng)變成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變?yōu)?,j為1。事實上,有可能j到了0仍然不能滿足A[i+1]=B[j+1](比如A[8]="d"時)。因此,準(zhǔn)確的說法是,當(dāng)j=0了時,我們增加i值但忽略j直到出現(xiàn)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]是為了讓程序繼續(xù)做下去,因為我們有可能找到多處匹配。     這個程序或許比想像中的要簡單,因為對于i值的不斷增加,代碼用的是for循環(huán) 。因此,這個代碼可以這樣形象地理解:掃描字符串A,并更新可以匹配到B的什么位置。     現(xiàn)在,我們還遺留了兩個重要的問題:一,為什么這個程序是線性的;二,如何快速預(yù)處理P數(shù)組。     為什么這個程序是O(n)的?其實,主要的爭議在于,while循環(huán)使得執(zhí)行次數(shù)出現(xiàn)了不確定因素。我們將用到時間復(fù)雜度的攤還分析中的主要策略,簡單地說就是通過觀察某一個變量或函數(shù)值的變化來對零散的、雜亂的、不規(guī)則的執(zhí)行次數(shù)進行累計。KMP的時間復(fù)雜度分析可謂攤還分析的典型。我們從上述程序的j 值入手。每一次執(zhí)行while循環(huán)都會使j減小(但不能減成負(fù)的),而另外的改變j值的地方只有第五行。每次執(zhí)行了這一行,j都只能加1;因此,整個過程中j最多加了n個1。于是,j最多只有n次減小的機會(j值減小的次數(shù)當(dāng)然不能超過n,因為j永遠是非負(fù)整數(shù))。這告訴我們,while循環(huán)總共最多執(zhí)行了n次。按照攤還分析的說法,平攤到每次for循環(huán)中后,一次for循環(huán)的復(fù)雜度為O(1)。整個過程顯然是O(n)的。這樣的分析對于后面P數(shù)組預(yù)處理的過程同樣有效,同樣可以得到預(yù)處理過程的復(fù)雜度為O(m)。     預(yù)處理不需要按照P的定義寫成O(m^2)甚至O(m^3)的。我們可以通過P[1],P[2],…,P[j-1]的值來獲得P[j]的值。對于剛才的B="ababacb",假如我們已經(jīng)求出了P[1],P[2],P[3]和P[4],看看我們應(yīng)該怎么求出P[5]和P[6]。P[4]=2,那么P [5]顯然等于P[4]+1,因為由P[4]可以知道,B[1,2]已經(jīng)和B[3,4]相等了,現(xiàn)在又有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。這里想不通的話可以仔細(xì)看一下:         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。     怎么這個預(yù)處理過程跟前面的KMP主程序這么像呢?其實,KMP的預(yù)處理本身就是一個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算法只預(yù)處理B串,因此這種算法很適合這樣的問題:給定一個B串和一群不同的A串,問B是哪些A串的子串。     串匹配是一個很有研究價值的問題。事實上,我們還有后綴樹,自動機等很多方法,這些算法都巧妙地運用了預(yù)處理,從而可以在線性的時間里解決字符串的匹配。我們以后來說。     昨天發(fā)現(xiàn)一個特別暈的事,知道怎么去掉BitComet的廣告嗎?把界面語言設(shè)成英文就行了。     還有,金山詞霸和Dr.eye都可以去自殺了,Babylon素王道。 Matrix67原創(chuàng)

責(zé)任編輯:

標(biāo)簽:

相關(guān)推薦:

精彩放送:

新聞聚焦
Top 欧美网址在线观看-亚洲最新毛片-国产成人免费爽爽爽视频-亚洲一区在线影院-日韩欧美在线观看视频网站-男女激情四射-成人一区二区免费看-欧美亚洲综合在线-日韩一级视频在线播放-国产成人三级视频在线播放-亚洲中文字幕日产无码2020-99久久久国产精品免费无卡顿-av在线观看地址-果冻传媒mv免费播放在线观看-欧美在线观看视频免费-日韩天天操

        成人免费观看视频在线观看| 亚洲精品国产suv一区88| 久久久久久久久久毛片| 美女扒开大腿让男人桶| 日本日本19xxxⅹhd乱影响| 可以在线看黄的网站| 国产美女18xxxx免费视频| 乱人伦xxxx国语对白| 精品嫩模一区二区三区| 日本中文字幕一级片| 成人av在线播放观看| 真人抽搐一进一出视频| 性生交免费视频| 国产毛片视频网站| www婷婷av久久久影片| 在线观看成人免费| 福利视频免费在线观看| 久久综合色视频| 狠狠97人人婷婷五月| 亚洲精品乱码久久久久久自慰| 37pao成人国产永久免费视频| 北条麻妃在线视频观看| 日本高清免费观看| 色姑娘综合天天| 日本人体一区二区| 亚洲一级免费观看| 五月天综合婷婷| www污在线观看| 9l视频白拍9色9l视频| 最新av免费在线观看| 少妇大叫太大太粗太爽了a片小说| 男人的天堂狠狠干| 在线观看av日韩| 男女裸体影院高潮| 天天爱天天操天天干| 国产男女激情视频| 色中文字幕在线观看| 97视频久久久| www.久久com| 国产福利视频在线播放| 国产日韩欧美大片| 污网站在线免费| 久热在线视频观看| 欧美黑人经典片免费观看| 涩涩网站在线看| 久久久久久久久久久久久国产| 996这里只有精品| 亚洲狼人综合干| 浮妇高潮喷白浆视频| 免费看av软件| www.国产福利| 亚洲污视频在线观看| 国产精品丝袜久久久久久消防器材 | 992tv成人免费观看| 999香蕉视频| 真人抽搐一进一出视频| 免费观看黄色大片| 色网站在线视频| av免费观看国产| 中文字幕乱码免费| 性久久久久久久久久久久久久| 亚洲成熟丰满熟妇高潮xxxxx| 男人添女荫道口女人有什么感觉| 视频在线观看免费高清| 成人精品视频一区二区| 男人操女人逼免费视频| 亚洲不卡中文字幕无码| 国内国产精品天干天干| 欧美精品一区二区三区免费播放| 激情内射人妻1区2区3区| www.夜夜爱| www.99热这里只有精品| 成人在线观看你懂的| 和岳每晚弄的高潮嗷嗷叫视频| 樱花草www在线| 黄色www在线观看| 日韩专区第三页| 激情深爱综合网| chinese少妇国语对白| 毛片av免费在线观看| 能看的毛片网站| 人人干人人干人人| 麻豆tv在线播放| 美女福利视频在线| 中文字幕国产传媒| www.-级毛片线天内射视视| 精品国产乱码久久久久久1区二区| 亚洲美女性囗交| 日本福利视频网站| 2022亚洲天堂| 日韩国产小视频| 日本免费黄视频| 欧美精品 - 色网| 全黄性性激高免费视频| 国产在线青青草| 亚洲天堂av一区二区三区| 成年丰满熟妇午夜免费视频 | 免费看欧美黑人毛片| 日韩欧美xxxx| 99热都是精品| 国产不卡一区二区视频| aaa毛片在线观看| 久久婷婷五月综合色国产香蕉| 超碰在线97免费| 国产日韩欧美大片| 日韩中文字幕a| 大肉大捧一进一出好爽视频| 成人综合久久网| 日韩欧美亚洲另类| 免费看又黄又无码的网站| 九一精品久久久| 国产男女在线观看| 国产一区二区三区乱码| 色啦啦av综合| 青青在线免费观看视频| 日韩成人三级视频| 超碰中文字幕在线观看| 密臀av一区二区三区| 国产精品12345| 欧美人与动牲交xxxxbbbb| 欧美成人福利在线观看| 成人观看免费完整观看| www.av蜜桃| 天堂在线中文在线| 好男人www社区| 男人插女人下面免费视频| 欧美综合在线播放| 欧美亚洲日本一区二区三区| 欧洲精品在线播放| 成人国产一区二区三区| 午夜久久久久久久久久久| 亚洲色图偷拍视频| 人人妻人人澡人人爽欧美一区| 日本特黄a级片| 自拍偷拍一区二区三区四区| 日韩中文字幕免费在线| 成人精品小视频| 亚洲欧美日韩精品一区| 久久婷五月综合| www.日本久久| 人妻互换免费中文字幕| 福利视频免费在线观看| 精品免费久久久久久久| 日韩在线一区视频| 亚洲五月激情网| 美女扒开大腿让男人桶| 亚洲图片 自拍偷拍| 天天干天天色天天干| 欧洲美女和动交zoz0z| 成人在线观看你懂的| 精品免费国产一区二区| 久久人人爽av| 黄色小视频大全| 日本免费一级视频| 国产亚洲视频一区| 久久人人爽人人爽人人av| 国产亚洲精品网站| 亚洲精品第三页| 无码人妻少妇伦在线电影| 日本三区在线观看| 色男人天堂av| 岛国av在线免费| 国产老熟妇精品观看| 国产日韩成人内射视频| 日韩av加勒比| 欧美一级片中文字幕 | 手机av在线网站| 青青草成人免费在线视频| 九九热免费精品视频| 国产精品av免费| 中国丰满人妻videoshd| 992kp免费看片| 精品人妻一区二区三区四区在线| 亚洲精品乱码久久久久久动漫| 2018日日夜夜| 一区中文字幕在线观看| 激情视频综合网| 欧美视频在线观看视频| 日韩福利视频在线| 噼里啪啦国语在线观看免费版高清版| 91色国产在线| 一女被多男玩喷潮视频| www国产无套内射com| 久久国产这里只有精品| 久久久999免费视频| 国产日产欧美一区二区| 小明看看成人免费视频| 欧美一级片中文字幕| 国产极品粉嫩福利姬萌白酱| 国产精品免费看久久久无码| 无码内射中文字幕岛国片| 九九热视频免费| 日韩欧美亚洲另类| 中文字幕国内自拍| 美女福利视频在线| 成人一级片网站| 国产成人精品视频ⅴa片软件竹菊| 日韩精品视频在线观看视频| 草草草视频在线观看| 国产资源第一页|