1. 程式人生 > >KMP(MP)演算法詳解

KMP(MP)演算法詳解

Written with StackEdit.
由於CSDN伺服器的維護,我迫不得已地用了和CSDN版本相近的StackEdit

KMP演算法,是一種字串匹配的演算法。當然,我們已經學過了一兩種字串匹配演算法,先來稍微回顧一下。
首先是暴力匹配,也就是將串中每一個長度等於另一串的子串和另一串進行匹配。若兩串的長度為nm,那麼其的時間複雜度顯然是O(nm)
然後是雜湊。雜湊在本質上是一種概率演算法,實際上是採用了一種對映的方法,如果將所有被雜湊之前的字串的集合設為A,而被雜湊之後的字串的雜湊值集合設為B,那麼也就相當於定義了一個對映Hash:AB,注意這不是一個單射,因為在大多數的情況下,有|

A|<|B|。當然,有很多方法改進,但是隻有完美雜湊使得它不再算一個概率演算法,然而完美雜湊本身的操作過於繁瑣,一般適用於字串不變的情況,如編譯器中的指令。實際上,雜湊演算法的本質和暴力是一致的,但是由於對映的存在,使得雜湊演算法要比較的東西就不那麼多了,就像暴力演算法中只抽樣比幾位一樣,但是雜湊演算法相當於是在每一位中都抽一點點的樣(有些時候不是這樣),所以更為準確一些。其的時間複雜度為Θ(n+mlogvMod),其中v是計算機所採用的進位制(如現在的一般採用二進位制,不排除以後有更高進位制的計算機,或者要求相關的互動題:)),Mod則是你所使用的模數(因為我們當時只學了一種雜湊:-()。
好吧,回顧完了,我們來稍微瞭解一些關於K
MP
的東西。KMP的本質是暴力匹配的優化,而其有一個較為簡單的版本,MP。本文介紹時將先介紹MP演算法,再比較KMPMP之間那一個K的不同。
考慮暴力演算法,其思路大致是用指標ij分別遍歷兩個串,然後當失配(即兩個指標對應的字元不相等時)回到兩個串“前面的位置”,也就是像回溯一樣不斷嘗試。
但是,這樣單純地找,有時是不會有好結果的。如下所示,兩個串AB

A:abababcB:ababc
其中,若在串A中找串B,那麼第一次嘗試匹配到ababa時,只有最後一位的ac不一樣。但是,這時我們注意到,串B中有兩個ab,所以當回溯時,我們並不用將串A中的指標i前移,而只需將B中的指標j
前移到開頭即可。若設A=a1a2a3a4B=b1b2b3b4,那麼因為已經比較,所以自然有a1=b1,a2=b2,a3=b3,a4=b4,於是又由於我們已知b1=b3,b2=b4,那麼就有b1=a3,b2=a4。所以,只需從原位置繼續開始即可。
MP演算法正是基於這樣的一種思想。倘若存在某個[1,j]=[ij,i],那麼我們定義j=next(i),表示當在i位置的字元失配時應當跳到哪裡。其的求法我們先不管,但是這樣一來匹配就很好寫了,程式碼這裡略去,請自行查詢資料。
那麼,next(i)的求法又應當是怎樣的呢?答案是:幾乎和匹配一樣!想想看,next(i)的求解,不正相當於是用自己匹配自己嗎?假如我們知道next(i),那麼我們能找到一個j,使得串S中有Si+1=Sj+1(當然,有時找不到,這時只需要設為一個特殊值就行了:))那麼這樣的話,就應當有next(i+1)=j+1
這,就是MP演算法的全套,至於KMP演算法,請自行查閱資料。

相關推薦

KMP(MP)演算法

Written with StackEdit. 由於CSDN伺服器的維護,我迫不得已地用了和CSDN版本相近的StackEdit KMP演算法,是一種字串匹配的演算法。當然,我們已經學過

KMP演算法及各種應用

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

(轉載)KMP演算法 (原創)KMP演算法

轉自https://www.cnblogs.com/yjiyjige/p/3263858.html (原創)詳解KMP演算法 作者:孤~影   KMP演算法應該是每一本《資料結構》書都會講的,算是知名度最高的演算法之一了,但很可惜,我大二那年壓根就沒看懂過~~~ 之後也在很多地方也都經常看

KMP演算法

KMP演算法應該是每一本《資料結構》書都會講的,算是知名度最高的演算法之一了,但很可惜,我大二那年壓根就沒看懂過~~~ 之後也在很多地方也都經常看到講解KMP演算法的文章,看久了好像也知道是怎麼一回事,但總感覺有些地方自己還是沒有完全懂明白。這兩天花了點時間總結一下,有

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

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

小白之KMP演算法及python實現

在看子串匹配問題的時候,書上的關於KMP的演算法的介紹總是理解不了。看了一遍程式碼總是很快的忘掉,後來決定好好分解一下KMP演算法,算是給自己加深印象。 ------------------------- 分割線-------------------------------

KMP字串匹配演算法

  KMP演算法利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現一個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度O(m+n)。 Next()函式的詳解 把將要進行next計算的字串S分成 k ,j 前後兩串,k代表前串開頭所在的序號,j

模式串匹配之KMP演算法

KMP演算法,是由Knuth,Morris,Pratt共同提出的模式匹配演算法,其對於任何模式和目標序列,都可以線上性時間內完成匹配查詢,而不會發生退化,是一個非常優秀的模式匹配演算法。但是相較於其他模式匹配演算法,該演算法晦澀難懂,第一次接觸該演算法的讀者往往會看得一頭

【模式匹配】之 —— KMP演算法及證明

本文所述KMP演算法原始碼可在這裡下載: Name Date Reason for change Revision 超然 2013.03.19 First version 1.0 超然 2013.04.15 Added

拓展KMP演算法

演算法描述:設字串T,長度為n,字串S,長度為m。線上性時間內求出T的每一個字尾所對應S的最長字首。 假設T=“AAAAB”,S="AAAA"。 我們從第一位開始匹配,匹配結果存放到ext陣列中。顯然ext【0】=4,然後我們就去計算ext【1】,顯然ext【1】=3。如果

KMP演算法, 關於NEXT陣列及其改進

關於KMP的總結 1.nextval陣列  具體含義: abcdefabc 在第二個c處匹配失敗 則應將j匹配到c上 即為j = 2 = 最大部分匹配長度; 這裡給出程式碼void get_nextval() { nextval[0] == -1; //初變數不得為0 注

KMP演算法 以及程式碼實現

KMP演算法求解什麼型別問題 字串匹配。給你兩個字串,尋找其中一個字串是否包含另一個字串,如果包含,返回包含的起始位置。 如下面兩個字串: char *str = "bacbababadababacambabacaddababacasdsd"; char *ptr = "

通俗易懂的KMP演算法(嚴蔚敏版C語言)

    最近,需要複習KMP演算法的next陣列,然後回頭看半年多後的我回頭看半年多前自己綜合別人內容寫的介紹。     沒錯,自己也看不懂。然後,自己再根據自己的理解寫了一下理解透徹的筆記,方便理解記憶,當然,以前的程式碼解釋部分可以參考,筆記演算法思維和演算法的實現有

KMP算法

ron 最短 回退 文本 字符指針 例子 比較 發現 != 本文的是基於我對鄧俊輝老師編著《數據結構(C++語言版)(第3版)》上關於KMP算法的理解,和網絡上一些大神們寫的博客,所寫。建議將我寫的關於implement strstr這題的博客和本篇連起來讀。 不難發現,這

KMP算法(轉)

不容易 浪費 成功 gif 字符串 重要 詳細 src text 網址http://www.cnblogs.com/tangzhengyue/p/4315393.html 網上有很多講解KMP算法的博客,我就不浪費時間再寫一份了。直接推薦一個當初我入門時看的博客吧:http

字符串kmp算法

kmp算法之前要研究aho-corasick算法 拖了好久 感覺自己博客要開始了!!aho-corasick算法依賴2元素:1.Trie樹解析,1個月前就已經寫過博客分析過了。2.KMP算法此文重點介紹字符串KMP算法:一開始說說普通模式算法("BF"算法)思路:模式串從主串的第一個字符

拓展KMP算法

上一個 problem clas 長度 nbsp sizeof 分析 get 沒有   拓展KMP解決的問題是給兩個串S和T,長度分別是n和m,求S的每一個後綴子串與T的最長公共前綴分別是多少,記作extend數組,也就是說extend[i]表示S[i,n-1](i從0開始

KMP算法V1

意義 最重要的 計算機 當前 [] 恰恰 ret 解析 信息 引言 KMP算法指的是字符串模式匹配算法,問題是:在主串T中找到第一次出現完整子串P時的起始位置。該算法是三位大牛:D.E.Knuth、J.H.Morris和V.R.Pratt同時發現的,以其名字首字母命名。在網

php openssl_sign() 語法+RSA公私鑰加密解密,非對稱加密演算法

其實有時候覺得寫部落格好煩,就個函式就開篇部落格。很小的意見事情而已,知道的人看來多取一舉,或者說沒什麼必要,浪費時間,不知道的人就會很鬱悶。技術就是這樣的,懂的人覺得真的很簡單啊,不知道的人真的好難。。。 一般在跟第三方介面對接資料的時候,為了保證很多都使用的RSA簽名,沒性趣瞭解的同學只需要

Show, attend and tell演算法及原始碼

mark一下,感謝作者分享! https://blog.csdn.net/shenxiaolu1984/article/details/51493673 原論文:https://arxiv.org/pdf/1502.03044v2.pdf 原始碼:https://github.c