KMP演算法詳解

2022-05-15 05:49:11 字數 2660 閱讀 8526

** 一.  簡單匹配演算法

先來看乙個簡單匹配演算法的函式:

int index_bf ( char s [ ], char t [ ], int pos )

else

j = nextval[j]; //子串移動到第nextval[j]個字元和主串相應字元比較

}}

下面是我寫的kmp模式匹配程式,各位可以測試一下。

#include#include#include#includeusing namespace std;

#define n 100010

char str1[n], str2[n];

int nextval[n];

int lens, lenp;

void getnext(const char *p, int nextval) //字首函式(滑步函式)

else

j = nextval[j]; //子串移動到第nextval[j]個字元和主串相應字元比較

} cout<<"字首函式為:"<

五.其他表示模式值的方法

上面那種串的模式值表示方法是最優秀的表示方法,從串的模式值我們可以得到很多資訊,以下稱為第一種表示方法。第二種表示方法,雖然也定義next[0]= -1,但後面絕不會出現 -1,除了next[0],其他模式值next[j]=k(0≤k

下面給出幾種方法的例子:

表一。下標01

2345

678t

abab

caab

c(1) next-10

-102-1

102(2) next-10

0120

112(3) next01

0130

213第三種表示方法,在我看來,意義不是那麼明了,不再討論。

表二。下標01

234t

abca

c(1)next-10

0-11(2)next-10

001表三。下標0

1234

567t

adca

dcad

(1)next-10

0-100

-10(2)next-10

0012

34對比串的模式值第一種表示方法和第二種表示方法,看錶一:

第一種表示方法next[2]= -1,表示t[2]=t[0],且t[2-1] !=t[0]

第二種表示方法next[2]= 0,表示t[2-1] !=t[0],但並不管t[0] 和t[2]相不相等。

第一種表示方法next[3]= 0,表示雖然t[2]=t[0],但t[1] ==t[3]

第二種表示方法next[3]= 1,表示t[2] =t[0],他並不管t[1] 和t[3]相不相等。

第一種表示方法next[5]= -1,表示t[5]=t[0],且t[4] !=t[0],t[3]t[4] !=t[0]t[1],t[2]t[3]t[4] !=t[0]t[1]t[2]

第二種表示方法next[5]= 0,表示t[4] !=t[0],t[3]t[4] !=t[0]t[1] ,t[2]t[3]t[4] !=t[0]t[1]t[2],但並不管t[0] 和t[5]相不相等。換句話說:就算t[5]==』x』,或 t[5]==』y』,t[5]==』9』,也有next[5]= 0 。

從這裡我們可以看到:串的模式值第一種表示方法能表示更多的資訊,第二種表示方法更單純,不容易搞錯。當然,用第一種表示方法寫出的模式匹配函式效率更高。比如說,在串s=「adcadcbdadcadcad 9876543」中匹配串t=「adcadcad」, 用第一種表示方法寫出的模式匹配函式,當比較到s[6] != t[6] 時,取next[6]= -1(表三),它可以表示這樣許多資訊:s[3]s[4]s[5]==t[3]t[4]t[5]==t[0]t[1]t[2],而s[6]

!= t[6],t[6]==t[3]==t[0],所以s[6] != t[0],接下來比較s[7]和t[0]吧。如果用第二種表示方法寫出的模式匹配函式,當比較到s[6] != t[6] 時,取next[6]= 3(表三),它只能表示:s[3]s[4]s[5]== t[3]t[4]t[5]==t[0]t[1]t[2],但不能確定t[6]與t[3]相不相等,所以,接下來比較s[6]和t[3];又不相等,取next[3]= 0,它表示s[3]s[4]s[5]== t[0]t[1]t[2],但不會確定t[3]與t[0]相不相等,即s[6]和t[0] 相不相等,所以接下來比較s[6]和t[0],確定它們不相等,然後才會比較s[7]和t[0]。是不是比用第一種表示方法寫出的模式匹配函式多繞了幾個彎。

所以,我們使用的話,盡量還是使用第一種方法好。

六.後話--kmp的歷史

cook於2023年證明的乙個理論得到,任何乙個可以使用被稱為下推自動機的計算機抽象模型來解決的問題,也可以使用乙個實際的計算機(更精確的說,使用乙個隨機訪問機)在與問題規模對應的時間內解決。特別地,這個理論暗示存在著乙個演算法可以在大約m+n的時間內解決模式匹配問題,這裡m和n分別是儲存文字和模式串陣列的最大索引。knuth 和pratt努力地重建了 cook的證明,由此建立了這個模式匹配演算法。大概是同一時間,morris在考慮設計乙個文字編輯器的實際問題的過程中建立了差不多是同樣的演算法。這裡可以看到並不是所有的演算法都是「靈光一現」中被發現的,而理論化的電腦科學確實 在一些時候會應用到實際的應用中。

KMP演算法詳解

模式匹配的kmp演算法詳解 這種由d.e.knuth,j.h.morris和v.r.pratt同時發現的改進的模式匹配演算法簡稱為kmp演算法。大概學過資訊學的都知道,是個比較難理解的演算法,今天特把它搞個徹徹底底明明白白。注意到這是乙個改進的演算法,所以有必要把原來的模式匹配演算法拿出來,其實理解...

KMP演算法詳解

kmp演算法即knuth morris pratt演算法,是模式匹配的一種改進演算法,因為是名字中三人同時發現的,所以稱為kmp演算法。因為偶然接觸到有關kmp的問題,所以上網查了一下next陣列和 nextval陣列的求法,卻沒有找到,只有在csdn的資料檔案裡找到了next陣列的簡單求法 根據書...

KMP演算法詳解

相信很多人 包括自己 初識kmp演算法的時候始終是丈二和尚摸不著頭腦,要麼完全不知所云,要麼看不懂書上的解釋,要麼自己覺得好像心裡了解kmp演算法的意思,卻說不出個究竟,所謂知其然不知其所以然是也。經過七八個小時地仔細研究,終於感覺自己能說出其所以然了,又覺得資料結構書上寫得過於簡潔,不易於初學者接...