導航:首頁 > 源碼編譯 > kmp演算法表示

kmp演算法表示

發布時間:2023-11-30 09:25:15

① KMP是什麼意思

kmp演算法是一種改進的字元串匹配演算法,由D.E.Knuth與V.R.Pratt和J.H.Morris同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱KMP演算法)。KMP演算法的關鍵是根據給定的模式串W1,m,定義一個next函數。next函數包含了模式串本身局部匹配的信息。
完全掌握KMP演算法思想
學過數據結構的人,都對KMP演算法印象頗深。

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

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

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

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

③ KMP是什麼意思

一種由Knuth(D.E.Knuth)、Morris(J.H.Morris)和Pratt(V.R.Pratt)三人設計的線性時間字元串匹配演算法。這個演算法不用計算變遷函數δ,匹配時間為Θ(n),只用到輔助函數π[1,m],它是在Θ(m)時間內,根據模式預先計算出來的。數組π使得我們可以按需要,「現場」有效的計算(在平攤意義上來說)變遷函數δ。粗略地說,對任意狀態q=0,1,…,m和任意字元a∈Σ,π[q]的值包含了與a無關但在計算δ(q,a)時需要的信息。由於數組π只有m個元素,而δ有Θ(m∣Σ∣)個值,所以通過預先計算π而不是δ,使得時間減少了一個Σ因子。

④ 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

大一下參加學校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就是串匹配演算法
運用自動機原理
比如說
我們在S中找P
設P={ababbaaba}
我們將P對自己匹配
下面是求的過程:{依次記下匹配失敗的那一位}
[2]ababbaaba
......ababbaaba[1]
[3]ababbaaba
........ababbaaba[1]
[4]ababbaaba
........ababbaaba[2]
[5]ababbaaba
........ababbaaba[3]
[6]ababbaaba
..............ababbaaba[1]
[7]ababbaaba
..............ababbaaba[2]
[8]ababbaaba
.................ababbaaba[2]
[9]ababbaaba
.................ababbaaba[3]
得到Next數組『0,1,1,2,3,1,2,2,3』
主過程:
[1]i:=1 j:=1
[2]若(j>m)或(i>n)轉[4]否則轉[3]
[3]若j=0或a[i]=b[j]則【inc(i)inc(j)轉[2]】否則【j:=next[j]轉2】
[4]若j>m則return(i-m)否則return -1;
若返回-1表示失敗,否則表示在i-m處成功
若還不懂mail:[email protected]

參考一下這里吧:

http://www.chinaaspx.com/archive/delphi/4733.htm

⑦ 數據結構與演算法——字元串匹配問題(KMP演算法)

KMP演算法也是比較著名的模式匹配演算法。是由 D.E.Knuth,J.H.Morrs VR.Pratt 發表的一個模式匹配演算法。可以大大避免重復遍歷的情況。

如果使用暴風演算法的話,前面五個字母完全相等,直到第六個字母 "f" "x" 不相等。如下圖:

T = 「abcdex」
j 123456
模式串 abcdex
next[j] 011111

T = "abcabx"
j 123456
模式串T abcabx
next[j] 011123

T = "ababaaaba"
j———————123456789
模式串T——— ababaaaba
next[j]————011234223

T = "aaaaaaaab"
j———————123456789
模式串T——— aaaaaaaab
next[j]————012345678

next數組其實就是求解字元串要回溯的位置
假設,主串S= 「abcababca」;模式串T=「abcdex」,由以上分析得出next數組為011111,next數組意味著當主串與模式串不匹配時,都需要從第一個的位置重新比較。

KMP演算法也是有缺陷的,比如主串S=「aaaabcde」,模式串T= 「aaaaax」。next的數組就是012345;

當開始匹配時,當i= 5,j = 5時,我們發現字元"b"與字元「a」不相等,如上圖,j = next[5] = 4;

由於T串的第二、三、四、五位置的字元都與首位「a」相等,那麼可以用首位next[1]的值去取代與它相等的後續字元的next[j],那麼next數組為{0,0,0,0,0,5};

在求解nextVal數組的5種情況

⑧ kmp演算法的基本思想

主串:a
b
a
c
a
a
b
a
c
a
b
a
c
a
b
a
a
b
b,下文中我們稱作T
模式串:a
b
a
c
a
b,下文中我們稱作W
在暴力字元串匹配過程中,我們會從T[0]

W[0]
匹配,如果相等則匹配下一個字元,直到出現不相等的情況,此時我們會簡單的丟棄前面的匹配信息,然後從T[1]

W[0]匹配,循環進行,直到主串結束,或者出現匹配的情況。這種簡單的丟棄前面的匹配信息,造成了極大的浪費和低下的匹配效率。
然而,在KMP演算法中,對於每一個模式串我們會事先計算出模式串的內部匹配信息,在匹配失敗時最大的移動模式串,以減少匹配次數。
比如,在簡單的一次匹配失敗後,我們會想將模式串盡量的右移和主串進行匹配。右移的距離在KMP演算法中是如此計算的:在已經匹配的模式串子串中,找出最長的相同的前綴和後綴,然後移動使它們重疊。
在第一次匹配過程中
T:
a
b
a
c
a
a
b
a
c
a
b
a
c
a
b
a
a
b
b
W:
a
b
a
c
ab
在T[5]與W[5]出現了不匹配,而T[0]~T[4]是匹配的,現在T[0]~T[4]就是上文中說的已經匹配的模式串子串,現在移動找出最長的相同的前綴和後綴並使他們重疊:
T:
a
b
a
c
aab
a
c
a
b
a
c
a
b
a
a
b
b
W:
a
b
a
c
ab
然後在從上次匹配失敗的地方進行匹配,這樣就減少了匹配次數,增加了效率。
然而,有些同學可能會問了,每次都要計算最長的相同的前綴會不會反而浪費了時間,對於模式串來說,我們會提前計算出每個匹配失敗的位置應該移動的距離,花費的時間是常數時間。比如:
j012345W[j]abacabF(j)001012當W[j]與T[i]不匹配的時候,設置j
=
F(j-1)
文獻中,朱洪對KMP演算法作了修改,他修改了KMP演算法中的next函數,即求next函數時不但要求W[1,next(j)-1]=W[j-(next(j)-1),j-1],而且要求W[next(j)]<>W[j],他記修改後的next函數為newnext。顯然在模式串字元重復高的情況下,朱洪的KMP演算法比KMP演算法更加有效。
以下給出朱洪的改進KMP演算法和next函數和newnext函數的計算演算法。

閱讀全文

與kmp演算法表示相關的資料

熱點內容
華三交換機保存命令 瀏覽:597
命令方塊怎麼調鍵盤 瀏覽:841
不把密碼存在伺服器上怎麼辦 瀏覽:398
怎麼讓指令方塊的命令消失 瀏覽:543
用單片機做plc 瀏覽:404
雲伺服器進入子目錄命令 瀏覽:795
伺服器機櫃如何配電 瀏覽:578
怎麼刪除iphone資源庫里的app 瀏覽:940
pdf魚 瀏覽:648
單片機pcf8591什麼作用 瀏覽:805
sql命令學院 瀏覽:283
加密軟體在電腦那個盤 瀏覽:988
android獲取外部存儲 瀏覽:573
怎麼查自己家的伺服器地址 瀏覽:858
編程c語言工作好不好 瀏覽:569
單片機焊接地怎麼連接 瀏覽:694
游戲源碼怎麼抓 瀏覽:216
程序員幫大家引走怪物 瀏覽:16
手機網頁小游戲源碼 瀏覽:513
戰地一伺服器怎麼設置管理員 瀏覽:396