簡單模式匹配改進:KMP算法

回溯問題

上一講 BruteForce算法的結尾中,我們提到了BruteForce算法的缺點,其中一條就是回溯問題,導致效率降低。

什么是回溯呢?

假設目標串S = "aaaaaaaab" ?T="aaab" 當我們利用BruteForce算法時,前三次的"aaa"的比較是毫無意義的,換言之,就是影響了效率。

KMP算法

為了提高效率,因此我們要使用KMP算法。KMP算法是一種改進后的算法,并且是由D.E.Knuth、V.R.Pratt和J.H.Morris同時發現的,因此稱之為KMP算法。

其基本思想為:每當匹配過程中出現字符串比較不等時,不需要回溯指針,而是利用已經得到的“部分匹配”結果整體模式向右“滑動”盡可能遠的一段距離,繼續進行比較。

如何實現這個思想,換言之如何判斷得到部分匹配結果?這里我們需要完成KMP算法中的第一步也是核心步驟:模式串求最大真子串。

1.模式串求最大真子串

舉個栗子


當J = 0 時 按照上面的思維導圖公式,next[ j ] = -1



當 J = 1 時,next[ j ] = 0,因為我們想求模式串的最大真子串,而這個最大真子串是指不包含當前位置編號的字符,而是它前面的字符所構成的字符串里有沒有最大真子串,因為 J = 1 時,模式串只有一個 a ,所以構不成最大真子串,因此屬于其他情況,next[ j ] = 0


當 J = 2 時,next[ j ] = 1 ,因為當前位置編號的字符前面有2個 a,a 與 a 相等,滿足我們的公式,并且他們的最大真子串長度為1(因為一個字符的長度為1),所以,記 next[ 2 ] = 1


當 J = 3 時,next[ j ] = 2,因為同理,當前位置編號的字符前面有3個 a,第一個a與第二個a構成的字符串==第二個a與第三個a構成的字符串,長度為2,所以,記next[ 3 ] = 2


一次類推,最后的結果如圖所示,不再贅述了。下圖為另一個例子,大家可以對照答案看看有沒有掌握好。


PS:當 J = 8 時 ,應比較前七個字符中是否有最大真子串,我們發現只有第一個a 和 第七個 a 滿足公式,因此next[ 8 ] = 1

最大真子串的實現代碼!

最大真子串的算法需要理解,同學們跟著代碼的邏輯思路對照圖表理解效果更佳。

2.KMP算法原理

KMP算法原理:當Si ≠ Tj, 若模式串存在最大真子串,可將模式串T按照 k=next[ j ] 的值向右滑動,然后比較 Si 和 Tk ,若仍有Si ≠ Tk,則模式串T按照新的 k=next[ j ] 的值向右滑動后比較。這樣的過程一直進行到 k = next[ k ] = 0,此時若Si ≠ T0,則模式串T不再向右滑動,隨后比較Si + 1 和 T0 。

原理很枯燥而且很難理解,但還是要寫,顯得很高大上 ^_^ 大家能不看就不看吧~

我們還是根據例子和圖表來進行理解!

舉個栗子 例如:主串 S = "aaaaaaab" ?子串 = "aaaab" 采用KMP的模式匹配過程。

對應的最大真子串集如圖。

首先一次進行比較,發現aaaa全部相等,當 b 時也就是J = 4時,由于不匹配,所以整體向右滑動一格,并且比較子串的第四個a,以此類推,最后完全匹配時,僅需要10次,大大提升了效率!!!

KMP實現代碼!


兩個方法都寫在了KMP類里,同學們依然要跟著代碼分析一遍,重點是對于最大真子串的理解。

大家可以寫一個測試類,聲明兩個字符串,看一看匹配的輸出結果~

輸出結果為3哦!

KMP算法總結

KMP算法的效率是很高的,遇到相關算法題時也應該使用該算法進行解題,多多熟練也是好的嘛!

下一講我們將會講一個有意思的小游戲---彩票機選的算法與實現 期間用到的相關知識 我會整理在一節中 內容可能較多哦!

PS:有什么問題或者不解的地方可以評論,我都會一一就行回復的,如果有錯誤或者言語不明的地方,還請大神多多指點!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 數據結構與算法--KMP算法查找子字符串 部分內容和圖片來自這三篇文章: 這篇文章、這篇文章、還有這篇他們寫得非常...
    sunhaiyu閱讀 1,757評論 1 21
  • 引言 字符串匹配一直是計算機科學領域研究和應用的熱門領域,算法的改進研究一直是一個十分困難的課題。作為字符串匹配中...
    潮汐行者閱讀 1,689評論 2 6
  • 數據結構 第8講 KMP算法 講這個算法之前,我們首先了解幾個概念: 串:又稱字符串,是由零個或多個字符組成的有限...
    rainchxy閱讀 1,369評論 0 3
  • 何為豐滿人生? 行萬里路,讀萬卷書,識萬般人,悟萬種情,擁萬貫財,卻攜一人,白首一城。 可惜現實很骨感 只走百十里...
    從八到九閱讀 84評論 0 0
  • 2017.2.14關鍵詞:I型,溝通,影響 通過與@孫穎琪姐姐的溝通,更加明白了,I型真正在意的是自我的表達...
    生命君閱讀 176評論 0 0