1. 程式人生 > >七分鐘理解什麼是 KMP 演算法

七分鐘理解什麼是 KMP 演算法

本文是介紹 什麼是 BF演算法、KMP演算法、BM演算法 三部曲之一。

KMP演算法 內部涉及到的數學原理與知識太多,本文只會對 KMP演算法 的執行過程、 部分匹配表 、next陣列 進行介紹,如果理解了這三點再去閱讀其它有關 KMP演算法 的文章肯定能有個清晰的認識。

以下的文字描述請結合視訊動畫來閱讀~

視訊地址:https://www.bilibili.com/video/av60334201/

定義

Knuth-Morris-Pratt 字串查詢演算法,簡稱為 KMP演算法,常用於在一個文字串 S 內查詢一個模式串 P 的出現位置。

這個演算法由 Donald Knuth、Vaughan Pratt、James H. Morris 三人於 1977 年聯合發表,故取這 3 人的姓氏命名此演算法。

是不是感覺 Donald Knuth 這個名字很眼熟?沒錯,在前面 這或許是講解 Knuth 洗牌演算法最好的文章 一文中也出現了他!

下面直接給出 KMP演算法 的操作流程:

  • 假設現在文字串 S 匹配到 i 位置,模式串 P 匹配到 j 位置
  • 如果 j = -1,或者當前字元匹配成功(即 S[i] == P[j] ),都令 i++,j++,繼續匹配下一個字元;
    如果 j != -1,且當前字元匹配失敗(即 S[i] != P[j] ),則令 i 不變,j = next[j]。此舉意味著失配時,模式串 P相對於文字串 S 向右移動了 j - next [j] 位
  • 換言之,將模式串 P 失配位置的 next 陣列的值對應的模式串 P 的索引位置移動到失配處

看不明白?直接看動畫!

執行過程

以下圖文字串 S 與模式串 P 為例:

首先,列出模式串 P 的所有子串:

a       
a b            
a b a          
a b a a        
a b a a b      
a b a a b c    
a b a a b c a  
a b a a b c a c

然後,求得每一個子串的所有字首與字尾。

字首 指除了最後一個字元以外,一個字串的全部頭部組合;字尾 指除了第一個字元以外,一個字串的全部尾部組合。

以第五列為例進行演示。

字首為

a   
a b    
a b a  
a b a  

字尾為

b   
a b    
a A b  
b a a b

因此,它的字首字尾的公共元素的最大長度為 2。

求得原模式串 P 的子串對應的各個字首字尾的公共元素的 最大長度表 下圖。

根據最大長度表 去求 next 陣列:next 陣列相當於“最大長度值” 整體向右移動一位,然後初始值賦為-1。

好了,獲取了 next 陣列 後,KMP 演算法 的操作就很清晰了。

將模式串 P 與文字串 S 的字母一個個進行匹配,當失配的時候,模式串向右移動。

怎麼移動?

比如模式串的 b 與文字串的 c 失配了,找出失配處模式串的 next陣列 裡面對應的值,這裡為 0,然後將索引為 0 的位置移動到失配處。

相關推薦

分鐘理解什麼是 KMP 演算法

本文是介紹 什麼是 BF演算法、KMP演算法、BM演算法 三部曲之一。 KMP演算法 內部涉及到的數學原理與知識太多,本文只會對 KMP演算法 的執行過程、 部分匹配表 、next陣列 進行介紹,如果理解了這三點再去閱讀其它有關 KMP演算法 的文章肯定能有個清晰的認識。 以下的文字描述請結合視訊動畫來閱

循序漸進,深入理解KMP演算法

KMP演算法是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同時發現的。其中第一位就是《計算機程式設計藝術》的作者! KMP演算法要解決的問題就是在字串(也叫主串)中的模式(pattern)定位問題。說簡單點就是我們平時常說的關鍵字搜尋。模式串就是關鍵字(接下來

從DFA角度理解KMP演算法

KMP 演算法 KMP(Knuth-Morris-Pratt)演算法在字串查詢中是很高效的一種演算法,假設文字字串長度為n,模式字串長度為m,則時間複雜度為O(m+n),最壞情況下能提供線性時間執行時間保證。 《演算法導論》和其他地方在講解KMP演算法的時候

KMP之一:從頭到尾徹底理解KMP演算法(2014年8月1日版)

作者:July 時間:最初寫於2011年12月,2014年7月21日晚10點 全部刪除重寫成此文。 1. 引言     本KMP原文最初寫於2年多前的2011年12月,因當時初次接觸KMP,思路混亂導致寫也寫得非常混亂,如此,留言也是“罵聲”一片。所以一直想找機會重新寫下KMP,但苦於一直以來對KMP的理

簡單理解KMP演算法

KMP演算法是迄今為止最為高效的字串匹配演算法。當然,在KMP演算法出現之前,有關字串的匹配問題當然經過了一個漫長的探索過程。從一開始最簡單的樸素字串匹配演算法,到Rabin-Karp演算法,再到有限自動機演算法等等,可以說任何一個偉大演算法的誕生都不可能是一朝

透徹理解KMP演算法

好好打下字串演算法基礎。本篇通俗、透徹地解釋線性時間複雜度的字串匹配演算法:KMP演算法。 之前寫過KMP演算法,但時間久了回顧起來還是要花點兒時間,覺得需要進一步加深;現在就試圖徹底吃透它。若是感興趣豆友們能得到一點點的幫助就更好了~ 別忘了點個贊:-) KMP 演算法的

KMP演算法淺顯理解

說明:轉載 KMP演算法看懂了覺得特別簡單,思路很簡單,看不懂之前,查各種資料,看的稀裡糊塗,即使網上最簡單的解釋,依然看的稀裡糊塗。 我花了半天時間,爭取用最短的篇幅大致搞明白這玩意到底是啥。 這裡不扯概念,只講演算法過程和程式碼理解: KMP演算法求解什麼型別問題 字串匹配。給

KMP演算法最淺顯理解

說明 KMP演算法看懂了覺得特別簡單,思路很簡單,看不懂之前,查各種資料,看的稀裡糊塗,即使網上最簡單的解釋,依然看的稀裡糊塗。  我花了半天時間,爭取用最短的篇幅大致搞明白這玩意到底是啥。  這裡不扯概念,只講演算法過程和程式碼理解: KMP演算法求解什麼型別問題

KMP 演算法(1):如何理解 KMP

http://www.61mon.com/index.php/archives/183/ 系列文章目錄 KMP 演算法(1):如何理解 KMPKMP 演算法(2):其細微之處 一:背景TOC 給定一個主字串(以 S 代替)和模式串(以 P 代替),要

KMP演算法的簡單理解 【筆記】

//本文除實現程式碼外全部為原創內容 轉載請註明出處  程式碼來自這裡 kmp演算法是一種改進的字串匹配演算法,由D.E.Knuth與V.R.Pratt和J.H.Morris同時發現,故稱KMP演算法 字串匹配:從字串T中尋找字串P出現的位置(P遠小於T)。其中P稱為“模式”

KMP演算法理解

概述 這篇文章本來寫在了word文件裡,兩天倉促寫了這些東西,但不知不覺就搞了16頁的word,為了留存勞動成果,發一遍存到部落格上。文章幾乎一直在用失配後如何選擇新的合適的起點來說這個演算法,總之就是為了減少不必要的匹配,直接判掉某些匹配起始點,再就是匹配時主串是不會回退的。 說明 為

每天進步一點點——五分鐘理解一致性雜湊演算法(consistent hashing)

根據上面的圖解分析,一致性雜湊演算法滿足了單調性和負載均衡的特性以及一般hash演算法的分散性,但這還並不能當做其被廣泛應用的原由,因為還缺少了平衡性。下面將分析一致性雜湊演算法是如何滿足平衡性的。hash演算法是不保證平衡的,如上面只部署了NODE1和NODE3的情況(NODE2被刪除的圖),object1

對基本KMP演算法理解

kmp演算法是在bf(暴力搜尋)演算法的基礎上進行優化,以減少重複操作,降低時間複雜度的一種字串匹配演算法。 kmp演算法的思想 如何搜尋某字串的子串?暴力搜尋的思想是將子串的第一個元素s[0]與a[0]匹配,如果成功則判斷s[1]與a[1],否則s向右移動

KMP演算法最淺顯理解——一看就明白

說明 KMP演算法看懂了覺得特別簡單,思路很簡單,看不懂之前,查各種資料,看的稀裡糊塗,即使網上最簡單的解釋,依然看的稀裡糊塗。 我花了半天時間,爭取用最短的篇幅大致搞明白這玩意到底是啥。 這裡不扯概念,只講演算法過程和程式碼理解: KMP演算法求解

KMP演算法中關於next陣列的j=next[j]理解

這篇文章是在oneNote上寫的,小弟不懂oneNote怎麼轉成md,所以只能笨辦法截圖上來了。。。覺得看的費勁的可以找我要原本 聯絡方式郵箱: [email protected]

kmp演算法(最簡單最直觀的理解,看完包會)

本文將以特殊的方式來讓人們更好地理解kmp演算法,不包括kmp演算法的推導,接下來,我們將從樸素演算法出發。 在這之前,我們先設主串為S,模式串為T,我們要解決的詢問是主串中是否包含模式串(即T是否為S的子串)。 版權宣告:本文為原創文章,轉載請標明出處。

史上最好理解KMP演算法

暴力匹配演算法 首先,我假設你已經是一個已經懂暴力匹配演算法的人了。 但是暴力匹配演算法有一個問題:當你知道你的目標串和搜尋串不匹配的時候,它已經附帶了一些資訊。 比如在如圖匹配,實際上目標串已經匹配到了第七個字元D 如果接下來你還是把A往後

字串匹配——KMP演算法中的next陣列理解

關於原理就不講了,只說下我對Next陣列的理解,希望可以讓你獲得靈光一閃。 其實最難的就是是j=Next[j];這麼一句話,當時思考了很長時間,終於明白的時候確實很興奮加得意。 #include<cstdio> #include<cstring> v

KMP演算法理解

什麼是KMP演算法? 模式串 char[] pat = new char[M]; 文字串 char[] txt = new char[N]; 假設當前正在比較的字元是txt[i]和pat[j], 即pat[0, j - 1]已經匹配成功。txt[i]後面的字元處於未知狀態。

KMP演算法next陣列計算的理解——菜鳥福音

我的文章莫名找不到了。。。還是再寫一遍吧,希望對了解KMP的演算法有點幫助…… 首先寫幾點 1)本文討論的KMP主要是嚴蔚敏的《資料結構》中第四章提到的KMP,即帶NEXT[]輔助陣列的KMP演算法 2)本文主要是討論KMP演算法NEXT[]陣列的計算的理