1. 程式人生 > >演算法相關——KMP演算法最通俗易懂的解釋

演算法相關——KMP演算法最通俗易懂的解釋

0.  前言

一個字串"BBCABCDABABCDABCDABDE"中是否包含另一個字串"ABCDABD" KMP就是最常用的字串匹配演算法之一。KMP有著優秀的時間複雜度O(m+n)網上有很多KMP演算法的解釋,但讀起來都很費勁。直到讀到Jake Boxer的文章,我才真正理解這種演算法。下面我用自己的語言,試圖寫一篇比較好懂的KMP演算法解釋。

1.  演算法過程解釋



首先,字串"BBCABCDAB ABCDABCDABDE"的第一個字元與搜尋詞"ABCDABD"的第一個字元,進行比較。因為BA不匹配,所以搜尋詞後移一位。


就這樣,直到字串有一個字元,與搜尋詞的第一個字元相同為止。


接著比較字串和搜尋詞的下一個字元,還是相同。



直到字串有一個字元,與搜尋詞對應的字元不相同為止。



這時,最自然的反應是,將搜尋詞整體後移一位,即從上圖B處再從頭逐個比較。這樣做雖然可行,但是效率很差,因為你要把搜尋的初始位置移到已經比較過的位置,重比一遍。


一個基本事實是,當空格與D不匹配時,你其實知道前面六個字元是"ABCDAB"KMP演算法的想法是,此時不只移動一位,移動數是已經比較的字元數 - 最後一個匹配字元所對應的部分匹配值,這個部分匹配值實質上就是字串頭部和尾部重複部分的最大長度。因此就有了部分匹配值陣列:





已知空格與D不匹配時,前面六個字元"ABCDAB"是匹配的。查表可知,最後一個匹配字元B對應的"部分匹配值"2,因此向後移動的位數為已匹配的字元數減去對應的部分匹配值,即

6-2=4


因為空格與C不匹配,搜尋詞還要繼續往後移。這時已匹配的字元數為2("AB"),最後一個匹配字元B對應的"部分匹配值"為0。所以,移動位數為 2,於是將搜尋詞向後移2位。


因為空格與A不匹配,繼續後移一位。



逐位比較,直到發現CD不匹配。於是,移動位數為 6 - 2,繼續將搜尋詞向後移動4位。



逐位比較,直到搜尋詞的最後一位,發現完全匹配,於是搜尋完成如果需要找出全部的匹配,移動位數為7 - 0,再將搜尋詞向後移動7位,剩下的操作就重複了。


2. 部分匹配值陣列的生成

首先,要了解兩個概念:字首和字尾

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

"字尾"指除了第一個字元以外,一個字串的全部尾部組合。

"部分匹配值"就是"字首"和"字尾"的最長的共有元素的長度。以"ABCDABD"為例:



//"A"的字首和字尾都為空集,共有元素的長度為0;
//"AB"的字首為[A],字尾為[B],共有元素的長度為0;
//"ABC"的字首為[A, AB],字尾為[BC, C],共有元素的長度0;
//"ABCD"的字首為[A, AB, ABC],字尾為[BCD, CD, D],共有元素的長度為0;
//"ABCDA"的字首為[A, AB, ABC, ABCD],字尾為[BCDA, CDA, DA, A],共有元素為"A",長度為1;
//"ABCDAB"的字首為[A, AB, ABC, ABCD, ABCDA],字尾為[BCDAB, CDAB, DAB, AB, B],共有元素為"AB",長度為2;
//"ABCDABD"的字首為[A, AB, ABC, ABCD, ABCDA, ABCDAB],字尾為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長度為0。

感謝:http://kb.cnblogs.com/page/176818/

相關推薦

演算法相關——KMP演算法通俗易懂解釋

0.  前言一個字串"BBCABCDABABCDABCDABDE"中是否包含另一個字串"ABCDABD"? KMP就是最常用的字串匹配演算法之一。KMP有著優秀的時間複雜度O(m+n),網上有很多KMP演算法的解釋,但讀起來都很費勁。直到讀到Jake Boxer的文章,我才真

轉自知乎-我見過通俗易懂KMP演算法詳解

有些演算法,適合從它產生的動機,如何設計與解決問題這樣正向地去介紹。但KMP演算法真的不適合這樣去學。最好的辦法是先搞清楚它所用的資料結構是什麼,再搞清楚怎麼用,最後為什麼的問題就會有恍然大悟的感覺。我試著從這個思路再介

全的通俗易懂演算法——排序演算法【1】

1、氣泡排序 氣泡排序的基本思想就是:從無序序列頭部開始,進行兩兩比較,根據大小交換位置,直到最後將最大(小)的資料元素交換到了無序佇列的隊尾,從而成為有序序列的一部分;下一次繼續這個過程,直到所有資料元素都排好序。 # python [升序的排序] s = [3,4

歸併排序非遞迴演算法通俗易懂的解析

分析: 非遞迴,即迭代,與遞迴最大的區別在於實現的方向不同。遞迴拆開來是“遞推”與“迴歸”,也就是先從頂層往下,逐層遞推到底層,再從底層逐層迴歸到頂層,所以mergesort的遞迴版本是先從頂層開始往下不斷對陣列一分為二,到底層歸併,回到上一層,再歸併,重複直到頂層。非遞迴

通俗易懂的判定IPV4和IPV6的演算法

題目描述  輸入一個字串,檢查輸入是否為合法的IPV4或者IPV6地址。 IPV4地址: 由4組數字組成,每組數字由"."分隔,第1組每個數字在1到255之間,其餘組每個數字在0到255之間。如"172.16.254.1"是一個合法的地址,但是每組數字是不能包含前導0的,

我見過通俗易懂的快速排序過程講解,轉自《坐在馬桶上看演算法:快速排序》

如果以上C程式碼看不懂,請看下面java程式碼: public static int Partition(int[] a,int p,int r){   int x=a[r-1];   int i=p-1;   int temp;   for(int j=p;j<=

svm演算法 通俗易懂講解

  最近在學習svm演算法,藉此文章記錄自己的學習過程,在學習很多處借鑑了z老師的講義和李航的統計,若有不足的地方,請海涵;svm演算法通俗的理解在二維上,就是找一分割線把兩類分開,問題是如下圖三條顏色都可以把點和星劃開,但哪條線是最優的呢,這就是我們要考慮的問題; 首

圖解一致性雜湊演算法,全網(小區區域網)通俗易懂

很多同學應該都知道什麼是雜湊函式,在後端面試和開發中會遇到「一致性雜湊」,那麼什麼是一致性雜湊呢?名字聽起來很厲害的樣子,其實原理並不複雜,這篇文章帶你徹底搞懂一致性雜湊! 進入主題前,先來一場緊張刺激的模擬面試吧。 ![模擬面試表情.png](https://i.loli.net/2020/07/31/f

通俗易懂的NIO原理解釋

最通俗易懂的NIO原理解釋 NIO最核心的三個元件 Channel 通道 Buffer 緩衝區 Selector 選擇器 其中Channel對應以前的流,Buffer不是什麼新東西,Selector是因為nio可以使用同步的非堵塞模式才加入的東西。 以前的流總是堵塞的,一

講透大資料,我只需要一頓飯(通俗易懂的大資料解釋

十五年前,剛開始工作,從帝都回老家。 某長輩和藹的問我:“工作了啊,做什麼的?” 我躊躇半天答曰:“挨踢(IT)。” 長輩不假思索的來了一句:“哦,在中關村賣光碟啊!” 我......我.....我......(叔叔,你知道的太多了) 【副菜

【區塊鏈】目前對區塊鏈通俗易懂解釋

來源:網優僱傭軍物聯網智庫 整理髮布轉載請註明來源和出處------   【導讀】------這

通俗易懂的解讀比特幣相關原理

週末花時間看了一些比特幣原理相關的資料,雖然不敢說把每個細節都完全搞懂了,不過整體思路和關鍵部分的主要原理還是比較明白。寫一篇文章分享給大家。這篇文章的定位會比較科普,儘量用類比的方法將比特幣的基本原理講出來。這篇文章不會涉及演算法和協議中比較細節的部分,打算後面會再寫一篇程

什麼是區塊鏈?這是我見過的通俗易懂解釋

最近區塊鏈非常火,關注度和曝光度持續上升,國內眾多巨頭公司紛紛張開雙臂擁抱,把區塊鏈當做網際網路時代的偉大顛覆性創新,一窩蜂研究怎樣把區塊鏈變成自己搶佔商業先機的工具。 那麼,區塊鏈技術究竟是什麼呢?分開看每個漢字都認識,但是湊在一起就不知道是什麼意思了。針對大家覺得神祕無比的區塊鏈,現在有了一個最通俗

卷積的意義-是我所看到的解釋生動通俗易懂

卷積 最近總是和卷積打交道,工作需要,每天都要碰到它好幾次,不勝煩惱,因為在大學時候學訊號與系統的時候就沒學會,我於是心想一定要把卷積完全搞明白。正好同辦公室的同學也問我什麼是卷積,師姐昨天也告訴我說:"我也早就想把這個問題搞明白了!"經過一段時間的思考之後,有一些很

通俗易懂的DAPP解釋,瞭解一下?

傳統的APP相信大家已經耳熟能詳了,那麼傳統的APP具有哪些缺點呢?大致來說,APP目前存在以下幾個問題 1、強行捆綁推廣其他應用軟體; 2、未經使用者同意,收集、使用使用者個人資訊; 3、使用者不知情的情況下,自動向外發送資訊 4、造成手機頻繁卡頓 5、惡意收費

執行緒與程序通俗易懂解釋(附面試題與答案)

程序和執行緒都是一個時間段的描述,是CPU工作時間段的描述。一、CPU+RAM+各種資源(比如顯示卡,光碟機,鍵盤,GPS, 等等外設)構成我們的電腦,但是電腦的執行,實際就是CPU和相關暫存器以及RAM之間的事情。二、CPU太快,太快,太快了,暫存器僅僅能夠追的上他的腳步,RAM和別的掛在各總線上的裝置完全

區塊鏈是什麼(通俗易懂解釋

區塊鏈的本質是什麼?區塊鏈與比特幣有什麼關係?回答這兩個問題之前,我們先講一個拿石頭當錢的故事。 石幣之島 從前有個島嶼,數千人口,風景如畫,人們過著田園牧歌式的生活。然而,這個島最出名的原因是島上奇特的貨幣。一種又大又厚的石輪——“費幣”,這些石輪的直徑從1到12英寸不

通俗易懂解釋:正向代理與反向代理

題圖:柏林牆 本文來自劉志軍的投稿,微信公眾號“Python之禪” 維基百科對「代理伺服器」的解釋也是讓人一頭霧水,在計算機世界,代理可分為「正向代理」和「反向代理」,比

PID控制通俗解釋與PID參數的整定方法

但是 地理 3.0 超過 階段 特性 克服 bsp 缺點 轉自->這裏 PID是比例、積分、微分的簡稱,PID控制的難點不是編程,而是控制器的參數整定。參數整定的關鍵是正確地理解各參數的物理意義,PID控制的原理可以用人對爐溫的手動控制來理解。閱讀本文不需要高深的數

史上通俗易懂的理解雲計算

雲計算 阿裏雲 阿裏雲幸運券 “雲計算”這三個字相信你一定聽過無數遍了,那麽我想問問你,“雲計算”到底是什麽?你能回答出來嗎?首先我們聽到雲計算三個字時,感覺非常高大上,高不可測的,新技術等等,如果你沒有接觸過的,感覺離我們很遠,很不生活化,不像滴滴打車這麽生活化的應用軟件。 目錄導航:1、雲計算