導航:首頁 > 源碼編譯 > 王道有kmp演算法嗎

王道有kmp演算法嗎

發布時間:2023-03-02 01:33:30

⑴ KMP模式匹配演算法是什麼

KMP模式匹配演算法是一種改進演算法,是由D.E.Knuth、J.H.Morris和v.R.Pratt提出來的,因此人們稱它為「克努特-莫里斯-普拉特操作」,簡稱KMP演算法。此演算法可以在O(n+m)的時間數量級上完成串的模式匹配操作。其改進在於:每當一趟匹配過程出現字元不相等時,主串指針i不用回溯,而是利用已經得到的「部分匹配」結果,將模式串的指針j向右「滑動」盡可能遠的一段距離後,繼續進行比較。

1.KMP模式匹配演算法分析回顧圖4-5所示的匹配過程示例,在第三趟匹配中,當i=7、j=5字元比較不等時,又從i=4、j=1重新開始比較。然而,經仔細觀察發現,i=4和j=1、i=5和j=1以及i=6和j=1這三次比較都是不必進行的。因為從第三趟部分匹配的結果就可得出,主串中的第4、5和6個字元必然是b、c和a(即模式串第2、第2和第4個字元)。因為模式中的第一個字元是a,因此它無須再和這三個字元進行比較,而僅需將模式向右滑動2個字元的位置進行i=7、j=2時的字元比較即可。同理,在第一趟匹配中出現字元不等時,僅需將模式串向右移動兩個字元的位置繼續進行i=2、j=1時的字元比較。由此,在整個匹配過程中,i指針沒有回溯,如圖1所示。

圖1改進演算法的模式匹配過程示意

⑵ 關於KMP演算法的說明有什麼

(1)未改進的模式匹配演算法的時間復雜度為O(nm),但在一般情況下,其實際的執行時間接近O(n+m),因此至今仍被採用。

(2)KMP演算法僅當模式與主串之間存在許多「部分」匹配的情況下才顯得比未改進的模式匹配快。

(2)KMP演算法的最大特點是指示主串的指針不需要回溯,在整個匹配過程中,對主串僅需要從頭至尾掃描一遍,這對處理存儲在外存上的大文件是非常有效的。

⑶ 演算法-KMP

大一下參加學校ACM預備隊集訓的時候首次接觸KMP演算法,當時看了很多介紹文章,仍然不是很理解其實質,只是簡單地套模板AC題目,待大二數據結構與演算法課堂上再聽老師介紹一次,才恍然大悟其實KMP也就是那麼回事嘛。但當初為啥看那麼多文章都沒弄明白呢?正巧最近和朋友聊天時他告訴我他對KMP不是很理解,於是打算自己寫一篇文章,鞏固自己對KMP的認識,也希望能夠幫助更多朋友理解KMP。
在開始之前,需要知曉的概念:

前綴:以原串串頭為自身串頭的子串,如 的前綴有:
後綴:以原串串尾為自身串尾的子串,如 的後綴有:

注意:字元串前後綴都不包括該串本身

給你一個文本串T(Text String)

再給你一個模式串P(Pattern String)

問該模式串是否在文本串中,怎麼找?

一開始只好分別從文本串與模式串的串頭開始逐字母比較

二者相同,再比較T串與P串的下一位

如此反復

如果一直這么順利,兩串對應位置的字元總相同,待P串中最後一個字元也匹配完畢,說明該模式串在文本串中存在,耶( •̀ ω •́ )y超開心,查找結束。但,大多數匹配過程不會如此順利,在該例中,當匹配進行至

很明顯,失配了。現在怎麼辦?按樸素思想,將P串相對T串整體右移一位,重新開始匹配,即

但這種演算法效率無疑是十分低下的。設T串長度N,P串長度M,則樸素演算法時間復雜度為O(MN)

已知的重要信息並沒有被使用——已匹配的字元串前綴

在上例中,當P串最後一個字元匹配失敗時,其已有包含七個字元的 前綴子串S 匹配成功

完全可以利用前綴子串S做點什麼。觀察到在S串

中,有相同前後綴,即下圖藍色部分

而S串各字元又與T串中對應字元相同,即有

當失配發生後,直接將P串右移四位使S串藍色後綴部分對齊T串中藍色前綴部分

從圖中紅框部分繼續嘗試匹配,發現再次失配。這次,已匹配成功的前綴串S為

而在該串中沒有相同的前後綴,只能將P串串頭移至失配處進行比較

再次失配。此時前綴串S為空串,只好如樸素演算法般將P串整體右移一位,重新開始比較

匹配成功。於是又按照之前的步驟往下匹配,直至再次失配或匹配成功

後續步驟同上,不再贅述

上述示例已展現,KMP演算法的精髓在於對已匹配成功的前綴串S的利用

在樸素演算法中,匹配失敗了,T串待匹配字元會回溯

T串原本已匹配至T[7] = 'X',但是因為失配,需回溯到T[1] = 'b'重新開始匹配

而在KMP演算法中,若P[M]與T[K]匹配失敗,K不會回溯。既然匹配過程是從T[0]開始逐漸向右進行的,至T[K]失配發生時,T[0]至T[K-1]早已匹配過,何必再回溯過去重復匹配呢?於是乎,就如問題引入部分展示般

每當失配發生,我們總是去關注P串中已匹配成功的前綴串S

因為該前綴串是匹配成功的,說明在T串中必定存在與該前綴串相同的子串,記為S'

若S串中存在相同前後綴

則S'串必然也存在此相同前後綴

所以只需將P串右移四位,使得S串的該相同前綴對齊S'串的該相同後綴

再嘗試比較T[7]與P[3]

至於T[7]與P[3]是否能夠匹配另說(當然,本例中一看就知道沒匹配上),但通過對前綴串S的利用,成功省去了P串右移一位、兩位和三位後的無效匹配

繼續深入思考,給定一個具體的P串,其第N位的前綴串S內容是固定的,則S是否存在相同前後綴、相同前後綴的長度與內容也是確定的。換言之,對於一個具體的P串,當其與給定T串匹配至P[N]失配,P串應右移幾位再次與T串進行匹配也是確定的。我們完全可以使用一個數組記錄當P[N]失配後,應當使用N之前的哪一位再來與T串進行匹配,以此提高匹配效率,記該數組為Next數組

定義Next[i] = j表示當P串中第i位失配後,跳轉至P串第j位再次嘗試匹配

還是以之前的P串為例,它的Next數組求出來應為

取下標5為例,其前綴串為

最長相同前後綴為

若P[5]失配,應跳轉至P[1]再次嘗試匹配(最長相同前綴對應P[0],則取其後一位P[1],若存在多位,則取最後一位的下一位),P[5]的前一個字元P[4]對應字元'a',而P[1]前一個字元P[0]同對應字元'a',保證了P[1]之前字元與T串中對應字元保持匹配。所以Next[5] = 1,其餘下標對應Next數組值同如此求。

特別地,規定Next[0] = -1。而對於除下標0外的任意下標N,Next[N]的含義是 前N-1個已匹配成功的字元構成的前綴串S中,最長相同前後綴長度。 所以若在下標為N處匹配失敗了,則應前往Next[N]所對應的下標處匹配。

具體地,以下圖所示為例,P[6]與T[6]失配

而Next[6] = 2,所以使用P[2]再次嘗試與T[6]進行匹配

當求出P串Next數組後,便可快速進行與T串的匹配

現在問題只剩下如何求Next數組,注意到Next數組既然只與P串本身相關,與文本串T無關,故令P串與自身匹配即可求得

考慮字元串

其Next數組應為

令其與給定文本串相匹配

當匹配進行至

失配,於是跳轉至P[Next[3]] = P[1]處再次嘗試匹配

再度失配,也必然失配

問題在於不該出現P[N] =P[Next[N]]

若P[N] =P[Next[N]],則P[N]失配後使用P[Next[N]]再次嘗試匹配,由於P[N] =P[Next[N]],P[N]匹配失敗,P[Next[N]]必然也失敗

因此,若出現P[N] =P[Next[N]]情況,則令Next[N]=Next[Next[N]]

本例中該字元串新Next數組為

當匹配進行至

失配,於是跳轉至P[Next[3]] = P[0]處再次嘗試匹配

省去了之前跳轉至P[1]處的無效匹配

設T串長度M,P串長度N,由於KMP演算法不會回溯,分析易知時間復雜度為O(m+n)

對於P[N],若其前綴串S含相同前後綴F,且F長度為n(n>1),Next[N]可以取1至n中任意值,為最大化匹配效率考慮,總是取最大相同前後綴以提高效率,節省時間

⑷ kmp演算法詳解

KMP模式匹配演算法
KMP演算法是一種改進的字元串匹配演算法,其關鍵是利用匹配失敗後的信息,盡量減少模式串與主串的匹配次數以達到快速匹配的目的明[4]。
求得模式的特徵向量之後,基於特徵分析的快速模式匹配演算法(KMP模式匹配演算法)與樸素匹配演算法類似,只是在每次匹配過程中發生某次失配時,不再單純地把模式後移一位,而是根據當前字元的特徵數來決定模式右移的位數[3]。
include "string. h"

#include<assert. h>

int KMPStrMatching(String T, String P, int. N, int startIndex)

{int lastIndex=T.strlen() -P.strlen();

if((1 astIndex- startIndex)<0)//若 startIndex過大,則無法匹配成功

return (-1);//指向P內部字元的游標

int i;//指向T內部字元的游標

int j=0;//指向P內部字元的游標

for(i= startIndex; i <T.strlen(); i++)

{while(P[j]!=T[i]&& j>0)

j=N[j-1];

if(P[j]==T[i])

j++;

if(j ==P.strlen())

return(1-j+1);//匹配成功,返回該T子串的開始位置

}

return (-1);

}

⑸ kmp演算法什麼意思

KMP演算法之所以叫做KMP演算法是因為這個演算法是由三個人共同提出來的,就取三個人名字的首字母作為該演算法的名字。其實KMP演算法與BF演算法的區別就在於KMP演算法巧妙的消除了指針i的回溯問題,只需確定下次匹配j的位置即可,使得問題的復雜度由O(mn)下降到O(m+n)。
在KMP演算法中,為了確定在匹配不成功時,下次匹配時j的位置,引入了next[]數組,next[j]的值表示P[0...j-1]中最長後綴的長度等於相同字元序列的前綴。
對於next[]數組的定義如下:
1) next[j] = -1 j = 0
2) next[j] = max(k): 0<k<j P[0...k-1]=P[j-k,j-1]
3) next[j] = 0 其他
如:
P a b a b a
j 0 1 2 3 4
next -1 0 0 1 2
即next[j]=k>0時,表示P[0...k-1]=P[j-k,j-1]
因此KMP演算法的思想就是:在匹配過程稱,若發生不匹配的情況,如果next[j]>=0,則目標串的指針i不變,將模式串的指針j移動到next[j]的位置繼續進行匹配;若next[j]=-1,則將i右移1位,並將j置0,繼續進行比較。

閱讀全文

與王道有kmp演算法嗎相關的資料

熱點內容
伺服器如何搭建多個節點 瀏覽:322
acx演算法 瀏覽:252
幽冥詭匠漫畫全集用什麼app可以看 瀏覽:1001
租用伺服器為什麼越來越慢 瀏覽:960
演算法創新就業方向 瀏覽:423
演算法最優解作者 瀏覽:867
通達信紅綠寶塔線指標源碼 瀏覽:666
app是什麼東西合法嗎 瀏覽:231
怎麼鎖app視頻教程 瀏覽:841
迅捷pdf注冊碼生成器 瀏覽:748
androidsdkosx 瀏覽:302
壓縮面膜紙熒光 瀏覽:841
app怎麼分身三個 瀏覽:744
電影bt下載源碼 瀏覽:421
iwatch屏幕加密晶元 瀏覽:570
公安主題網站源碼 瀏覽:986
天津市伺服器供應商雲伺服器 瀏覽:115
數控車床子程序編程 瀏覽:111
floydwarshall演算法 瀏覽:717
丟失微信app怎麼找 瀏覽:252