KMP演算法詳解

2021-09-14 05:15:57 字數 2257 閱讀 4702

kmp演算法的核心,是乙個被稱為部分匹配表(partial match table)的陣列。對於字串「abababca」,它的pmt如下表所示:

如果待匹配的模式字串有8個字元,那麼pmt就會有8個值也就是表中的value。

字串的字首和字尾。如果字串a和b,存在a=bs,其中s是任意的非空字串,那就稱b為a的字首。例如,」harry」的字首包括,我們把所有字首組成的集合,稱為字串的字首集合。

字尾a=sb, 其中s是任意的非空字串,那就稱b為a的字尾,例如,」potter」的字尾包括,然後把所有字尾組成的集合,稱為字串的字尾集合。

要注意的是,字串本身並不是自己的字尾。pmt中的值是字串的字首集合與字尾集合的交集中最長元素的長度。

例如,對於」aba」,它的字首集合為,字尾 集合為。兩個集合的交集為,那麼長度最長的元素就是字串」a」了,長 度為1,所以對於」aba」而言,它在pmt表中對應的值就是1。再比如,對於字串」ababa」,它的字首集合為,它的字尾集合為, 兩個集合的交集為,其中最長的元素為」aba」,長度為3。

如圖1.12 所示,要在主字串"ababababca"中查詢模式字串"abababca"。

如果在 j 處字元不匹配,那麼主字串中 i 指標之前的 pmt[j −1] 位就一定與模式字串的第 0 位至第 pmt[j−1] 位是相同的。這是因為主字串在 i 位失配,也就意味著主字串從 i−j 到 i 這一段是與模式字串的 0 到 j 這一段是完全相同的。模式字串從 0 到 j−1 ,在這個例子中就是」ababab」,其字首集合與字尾集合的交集的最長元素為」abab」, 長度為4。所以,主字串中i指標之前的 4 位一定與模式字串的第0位至第 4 位是相同的,即長度為 4 的字尾與字首相同。這樣一來,我們就可以將這些字元段的比較省略掉。具體的做法是,保持i指標不動,然後將j指標指向模式字串的pmt[j −1]位即可。

簡言之,以圖中的例子來說,在 i 處失配,那麼主字串和模式字串的前邊6位就是相同的。又因為模式字串的前6位,它的前4位字首和後4位字尾是相同的,所以我們推知主字串i之前的4位和模式字串開頭的4位是相同的。就是圖中的灰色部分。那這部分就不用再比較了。

​​我們就可以使用pmt加速字串的查詢。我們看到如果是在 j 位 失配,那麼影響 j 指標回溯的位置的其實是第 j −1 位的 pmt 值,所以直接使用pmt陣列,而是將pmt陣列向後偏移一位。我們把新得到的這個陣列稱為next陣列。下面給出根據next陣列進行字串匹配加速的字串匹配程式。其中要注意的乙個技巧是,在把pmt進行向右偏移時,第0位的值,我們將其設成了-1,這只是為了程式設計的方便,並沒有其他的意義。本節的例子,next陣列如下表所示。

}如何快速求得next陣列。

其實,求next陣列的過程完全可以看成字串匹配的過程,即以模式字串為主字串,以模式字串的字首為目標字串,一旦字串匹配成功,那麼當前的next值就是匹配成功的字串的長度。

具體來說,就是從模式字串的第一位(注意,不包括第0位)開始對自身進行匹配運算。 在任一位置,能匹配的最長長度就是當前位置的next值。如下圖所示。

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演算法的意思,卻說不出個究竟,所謂知其然不知其所以然是也。經過七八個小時地仔細研究,終於感覺自己能說出其所以然了,又覺得資料結構書上寫得過於簡潔,不易於初學者接...