KMP演算法詳解

2021-09-23 06:17:18 字數 2479 閱讀 1843

kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度o(m+n)。

簡而言之kmp就是一種較為高效的字串匹配演算法,我們可以通過一道習題來理解它的大體思路:

現在有乙個字串str1 = 「abcabcabcde」,另外還存在乙個字串str2 = 「abcabcde」,現在請你設計乙個程式來判斷str2是不是str1的字串?

一般情況下我們拿到這道題,最開始的想法就是樸素匹配:

樸素匹配:

在第一次匹配時,由於『a』和『d』不匹配,所以我們將開始匹配的位置往後移一位,重新開始匹配,第二次匹配時,『a』和『c』不匹配,所以我們繼續往後移一位…,所以可以看出來,樸素匹配的時間複雜度是相當高的,已經達到了o(n2),如果字串相當長的情況下,那麼它所耗費的時間是相當長的,至於為什麼會耗費這麼長時間,那也是有原因的,樸素匹配在進行到兩個字元不匹配的時候,就會丟棄掉前面匹配過的結果,這就導致了前面的匹配過程都白做了,這就是時間耗費的一大主要地方,那麼我們能不能想出一種能夠利用到前面的匹配結果,來將後續的匹配進行加速呢?kmp就是這樣做的,它可以利用前面所匹配到的結果對後續的匹配過程進行加速,從而達到一種高效的匹配方法。

kmp演算法:

要是用kmp演算法,我們首先要了解到乙個概念,什麼是next陣列?

簡單來說,next陣列中的每乙個元素就是str2中對應字串的最長相同前字尾的長度(不包括當前字元),是不是很難理解,沒關係,看了下面這張圖,大家可能就會了解到什麼是next陣列了

當next陣列構造完成之後,我們就可以利用這個next陣列來加速我們的匹配過程,從而實現這種高效的kmp演算法

下面就是next陣列應用的具體流程:

當我們進行第一輪匹配時,發現str1中的『a』與str2中的『d』不匹配,這時我們不需要再從頭匹配了,只需檢視next陣列中『d』所對應的元素,然後將str2向右移至該元素i所對應的位置。由此來實現乙個巨大的跨越,這就是kmp演算法的主要思想,利用next陣列來加速匹配過程,其實我們不難發現,next陣列對應的前兩個元素一直是-1和0,在編寫程式的過程中,對於next陣列的求解也有一定的方法,下面就是對應的**:

vectorgetnext(string s2)

else if (next[tmp] <= 0)

else

}return next;

}

我們不難看出,其實在求解next陣列的過程中,我們可以採用求斐波那契數列的思想,用前乙個的值來求解出後乙個當然如果不相等的情況下,我們只需要再向前找,再去看next[i-1]所對應的值是否滿足這個規律,當找到最前面位置,則說明對於該字元而言,不存在公共前字尾,我們只需要將其置0即可。下面就是匹配過程的具體實現:

int getindexof(string s1, string s2,vectornext)

else if (next[j] == -1)

else

}if (j == s2.length())

return -1;

}

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