KMP(一) 模式匹配算法推導(dǎo) --《部分匹配表》


概述:本文主要在理論層面上分析KMP的基本實(shí)現(xiàn)原理以及《部分匹配表》推導(dǎo)過程;不涉及代碼實(shí)現(xiàn);如果您對KMP的實(shí)現(xiàn)代碼(OC)實(shí)現(xiàn)感興趣,可參考:
KMP(一) 模式匹配算法推導(dǎo) --《部分匹配表》
KMP(二) 模式匹配算法實(shí)現(xiàn)
KMP(三) 字符串快速匹配示例


一: KMP主要解決的問題:

KMP是三位大牛:D.E.Knuth凰慈、J.H.Morris和V.R.Pratt同時發(fā)現(xiàn)的死宣。其中第一位就是《計算機(jī)程序設(shè)計藝術(shù)》的作者G绻 唁奢!

KMP算法要解決的問題就是在字符串(也叫主串,下文統(tǒng)一稱"P")中快速高效匹配子串(下文統(tǒng)一稱"S")并確定S在P中位置的問題积暖。說簡單點(diǎn)就是我們平時常說的關(guān)鍵字(詞)搜索乎婿。

二. 字串樸素匹配算法實(shí)現(xiàn):

看一個樸素匹配算法示例:
主串: P="BBC ABCDAB ABCDABCDABDE" 長度為Length_p
字串: S = "ABCDABD" 長度為Length_s



首先今阳,字符串"BBC ABCDAB ABCDABCDABDE"的第一個字符與搜索詞"ABCDABD"的第一個字符,進(jìn)行比較逊躁。因?yàn)锽與A不匹配似踱,所以搜索詞后移一位。



因?yàn)锽與A不匹配稽煤,搜索詞再往后移核芽。



就這樣,直到字符串有一個字符酵熙,與搜索詞的第一個字符相同為止轧简。



接著比較字符串和搜索詞的下一個字符,還是相同匾二。


直到字符串有一個字符哮独,與搜索詞對應(yīng)的字符不相同為止。


這時察藐,最自然的反應(yīng)是借嗽,將搜索詞整個后移一位,再從頭逐個比較转培。這樣做雖然可行,但是效率很差浆竭,因?yàn)槟阋?搜索位置"移到已經(jīng)比較過的位置浸须,重比一遍,很明顯P的位置在回溯惨寿。分析樸素匹配算法時間復(fù)雜度為:
O((Length_p - Length_s + 1) * Length_s)

為方便后續(xù)說明,我們來約定一組表達(dá)規(guī)則:

主串 P 和字串 S 中有以下表達(dá),示例如:
P[0] = "B"
P[4] = "A"
P[0~5]="BBC AB"
S[0] = "A"
S[2]="C"
S[1~3]="BCD"

我們觀察一下此時字串 S 和 主串P:
以下重要:
當(dāng)S[0~5] = P[4~9] 并且 S[6] != P[10]時,S[0~3] 內(nèi)沒有重復(fù)的字符,而切S[0~3] =P[4~7],所以在進(jìn)行下一次比較時,我們可以直接將字串S移動至主串P的P[8] 位置開始比較,同時保持P的上一次查找位置不變(P[10]), 而不是像上圖一樣從P[5]開始循環(huán)比較,因?yàn)榇藭r的P[5~8] 不可能與S(主要看S[0~3])匹配 ;這樣效率會大大提升;接下來看KMP是如何做的;

三. KMP算法示例分析:

KMP核心原則: 保持主串P上次查找位置(index_p)不回溯,移動字串S到合適的位置(index_s),下次比較起始位置分別為P[index_p]和S[index_s],不在比較P[0~index_p] 和 S[0~index_s],從而達(dá)到簡化匹配的計算過程;具體示例如下:

這里要引入一個《部分匹配表》概念;部分匹配表推導(dǎo)過程稍后做解釋;我們要做的先學(xué)會如何利用《部分匹配表》去實(shí)現(xiàn)KMP模式匹配,從而理解KMP的匹配過程;字串移位計算公式如下:

移動位數(shù)(S) = 已匹配的字符數(shù) - 對應(yīng)的部分匹配值

接著上述利用《部分匹配表》匹配分析:


7.

已知空格與D不匹配時,前面6個字符"ABCDAB"是匹配的删窒。查表可知裂垦,最后一個匹配字符B對應(yīng)的"部分匹配值"為2,照上面的公式算出向后移動的位數(shù):
因?yàn)?6 - 2 等于4肌索,所以將S向后移動4位蕉拢。


8.

因?yàn)榭崭衽cC不匹配,搜索詞還要繼續(xù)往后移诚亚。這時晕换,已匹配的字符數(shù)為2("AB"),對應(yīng)B的"部分匹配值"為0站宗。所以闸准,移動位數(shù) = 2 - 0,結(jié)果為 2梢灭,于是將搜索詞向后移2位夷家。


9.

因?yàn)榭崭衽cA不匹配,而S已經(jīng)到達(dá)最左端,故P繼續(xù)后移一位敏释。


10.

逐位比較库快,直到發(fā)現(xiàn)C與D不匹配。于是钥顽,移動位數(shù) = 6 - 2义屏,繼續(xù)將搜索詞向后移動4位。


11.

逐位比較耳鸯,直到搜索詞的最后一位湿蛔,發(fā)現(xiàn)完全匹配,于是搜索完成县爬。如果還要繼續(xù)搜索(即找出全部匹配)阳啥,移動位數(shù) = 7 - 0,再將搜索詞向后移動7位财喳,這里就不再重復(fù)了察迟。

四. 《部分匹配表》計算過程

首先,要了解兩個概念:"前綴"和"后綴"耳高。 "前綴"指除了最后一個字符以外扎瓶,一個字符串的全部頭部組合;"后綴"指除了第一個字符以外泌枪,一個字符串的全部尾部組合概荷。注意:此處有個組合的概念,表達(dá)不同于KMP 算法實(shí)現(xiàn)中的前綴和后綴


"部分匹配值"就是"前綴"和"后綴"的最長的共有元素的長度。以"ABCDABD"為例碌燕,

1. "A"的前綴和后綴都為空集误证,共有元素的長度為0继薛;
2. "AB"的前綴為[A],后綴為[B]愈捅,共有元素的長度為0遏考;
3. "ABC"的前綴為[A, AB],后綴為[BC, C]蓝谨,共有元素的長度0灌具;
4. "ABCD"的前綴為[A, AB, ABC],后綴為[BCD, CD, D]譬巫,共有元素的長度為0咖楣;
5. "ABCDA"的前綴為[A, AB, ABC, ABCD],后綴為[BCDA, CDA, DA, A]缕题,共有元素為"A"截歉,長度為1;
6. "ABCDAB"的前綴為[A, AB, ABC, ABCD, ABCDA]烟零,后綴為[BCDAB, CDAB, DAB, AB, B]瘪松,共有元素為"AB",長度為2锨阿;
7. "ABCDABD"的前綴為[A, AB, ABC, ABCD, ABCDA, ABCDAB]宵睦,后綴為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長度為0墅诡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壳嚎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子末早,更是在濱河造成了極大的恐慌烟馅,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件然磷,死亡現(xiàn)場離奇詭異郑趁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)姿搜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門寡润,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舅柜,你說我怎么就攤上這事梭纹。” “怎么了致份?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵变抽,是天一觀的道長。 經(jīng)常有香客問我,道長绍载,這世上最難降的妖魔是什么太伊? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮逛钻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锰提。我一直安慰自己曙痘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布立肘。 她就那樣靜靜地躺著边坤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谅年。 梳的紋絲不亂的頭發(fā)上茧痒,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音融蹂,去河邊找鬼旺订。 笑死,一個胖子當(dāng)著我的面吹牛超燃,可吹牛的內(nèi)容都是我干的区拳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼意乓,長吁一口氣:“原來是場噩夢啊……” “哼樱调!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起届良,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤笆凌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后士葫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乞而,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年为障,在試婚紗的時候發(fā)現(xiàn)自己被綠了晦闰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡鳍怨,死狀恐怖呻右,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鞋喇,我是刑警寧澤声滥,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響落塑,放射性物質(zhì)發(fā)生泄漏纽疟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一憾赁、第九天 我趴在偏房一處隱蔽的房頂上張望污朽。 院中可真熱鬧,春花似錦龙考、人聲如沸蟆肆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炎功。三九已至,卻和暖如春缓溅,著一層夾襖步出監(jiān)牢的瞬間蛇损,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工坛怪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淤齐,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓酝陈,卻偏偏與公主長得像床玻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子沉帮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • 引言 字符串匹配一直是計算機(jī)科學(xué)領(lǐng)域研究和應(yīng)用的熱門領(lǐng)域锈死,算法的改進(jìn)研究一直是一個十分困難的課題。作為字符串匹配中...
    潮汐行者閱讀 1,650評論 2 6
  • 數(shù)據(jù)結(jié)構(gòu) 第8講 KMP算法 講這個算法之前穆壕,我們首先了解幾個概念: 串:又稱字符串待牵,是由零個或多個字符組成的有限...
    rainchxy閱讀 1,310評論 0 3
  • KMP算法是一種改進(jìn)的字符串匹配算法,由D.E.Knuth喇勋,J.H.Morris和V.R.Pratt三人同時發(fā)現(xiàn)缨该,...
    knowalker閱讀 1,327評論 2 9
  • 上午,起個大早川背,和剛露出頭的太陽一起贰拿,帶上大兒二兒直奔書畫班而去∠ㄔ疲看著周老師和已經(jīng)有點(diǎn)功底的學(xué)生展出的字畫膨更,大兒不...
    小鹿says閱讀 330評論 0 2
  • 我將那天的日期記在了本子上, 可是本子丟了缴允; 我去了你家幻想著你還在荚守, 可是那只是我的幻想; 你已經(jīng)走了,而我還停...
    畢之先生閱讀 446評論 1 1