KMP算法詳解


在數(shù)據(jù)結(jié)構(gòu)課上老師講了kmp算法非凌,但當(dāng)時并沒太懂,現(xiàn)在把思路重新理一遍荆针。

1.kmp算法簡介

KMP是三位大牛:D.E.Knuth敞嗡、J.H.Morris和V.R.Pratt同時發(fā)現(xiàn)的。
KMP算法其實就是一種改進(jìn)的字符串匹配算法航背,關(guān)鍵是利用匹配后失敗的信息喉悴,盡量減少模式串(W)與主串(T)的匹配次數(shù)以達(dá)到快速匹配的目的。具體實現(xiàn)就是實現(xiàn)一個next() 函數(shù)玖媚,函數(shù)本身包含了模式串的局部匹配信息箕肃。時間復(fù)雜度 O(m+n)
如果考慮最笨的方法今魔,我們可以將T[0]和W[0]進(jìn)行匹配勺像,如果相同則匹配下一個字符障贸,直到出現(xiàn)不相同的情況,此時我們會丟棄前面的匹配信息吟宦,然后把T[1]跟W[0]匹配篮洁,循環(huán)進(jìn)行,直到主串結(jié)束殃姓,或者出現(xiàn)匹配成功的情況袁波。這種丟棄前面的匹配信息的方法,時間復(fù)雜度為O(mn)辰狡。
KMP算法利用已經(jīng)部分匹配這個有效信息锋叨,保持i指針(主串)不回溯,通過修改j指針宛篇,讓模式串盡量地移動到有效的位置,具體可見下面一個例子薄湿。
如果主串為:a b c a b c d h i j k
模式串為:a b c e
當(dāng)我們匹配到主串的第四個字符a時叫倍,可知a和e不相等,因此需要移向下一位豺瘤,但其實我們并不需要從模式串中的第一位重新開始比較吆倦,因為主串中的前三個字符已經(jīng)沒有未匹配的a了,不可能匹配成功坐求。
[站外圖片上傳中...(image-f5d3d1-1518266644982)]

2.next()函數(shù)

因此蚕泽,最關(guān)鍵的是找到如何移動j指針。我們記當(dāng)匹配失敗時桥嗤,j要移動的下一個位置為k(即next[j]= k)须妻。記P為模式串。
很顯然泛领,存在這樣一個性質(zhì):最前面的k個位置(對于模式串來說)和j之前的最后k個字符(主串)是一樣的荒吏。因此得到公式:

P[0 ~ k-1] == P[j-k ~ j-1]

當(dāng)P[k] == p[j]時

有P[0 ~ k-1] + P[k] == p[j-k ~ j-1] + P[j],即:P[0 ~ k] == P[j-k ~ j]渊鞋,因此可得

next[j+1] == k + 1 == next[j] + 1

當(dāng)P[k] != p[j]時

我們只能在0~k-1中去尋找最長后綴串了绰更,因此為

k = next[k]

使用C++ 實現(xiàn)next函數(shù)為

    int* getNext(string p)
    {
        int* next = new int[p.length()];
        next[0] = -1;           //while the first char not match, i++,j++
        int j = 0;
        int k = -1;
        while (j < (int)p.length() - 1)
        {
            if (k == -1 || p[j] == p[k])
            {
                j++;
                k++;
                next[j] = k;
            }
            else
            {
                k = next[k];
            }
        }
        return next;
    }

3.完整算法

    int KMP(string T,string p)
    {
        int i=0;
        int j=0;
        int* next=getNext(T);
        while (i < (int)T.length() && j < (int)p.length())
        {
            if (j == -1 || T[i] == p[j])
            {
                i++;
                j++;
            }
            else
            {
                j=next[j];
            }
        }
        if (j == (int)p.length())
        {
            return i-j;
        }
        return -1;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市锡宋,隨后出現(xiàn)的幾起案子儡湾,更是在濱河造成了極大的恐慌,老刑警劉巖执俩,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徐钠,死亡現(xiàn)場離奇詭異,居然都是意外死亡奠滑,警方通過查閱死者的電腦和手機(jī)丹皱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門妒穴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摊崭,你說我怎么就攤上這事讼油。” “怎么了呢簸?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵矮台,是天一觀的道長。 經(jīng)常有香客問我根时,道長瘦赫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任蛤迎,我火速辦了婚禮确虱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘替裆。我一直安慰自己校辩,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布辆童。 她就那樣靜靜地躺著宜咒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪把鉴。 梳的紋絲不亂的頭發(fā)上故黑,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音庭砍,去河邊找鬼场晶。 笑死,一個胖子當(dāng)著我的面吹牛逗威,可吹牛的內(nèi)容都是我干的峰搪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼凯旭,長吁一口氣:“原來是場噩夢啊……” “哼概耻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起罐呼,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鞠柄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嫉柴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厌杜,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了夯尽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞧壮。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖匙握,靈堂內(nèi)的尸體忽然破棺而出咆槽,到底是詐尸還是另有隱情,我是刑警寧澤圈纺,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布秦忿,位于F島的核電站,受9級特大地震影響蛾娶,放射性物質(zhì)發(fā)生泄漏灯谣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一蛔琅、第九天 我趴在偏房一處隱蔽的房頂上張望胎许。 院中可真熱鬧,春花似錦罗售、人聲如沸呐萨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至切距,卻和暖如春朽缎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谜悟。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工话肖, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人葡幸。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓最筒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蔚叨。 傳聞我的和親對象是個殘疾皇子床蜘,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

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

  • 字符串匹配KMP算法詳解 1. 引言 以前看過很多次KMP算法,一直覺得很有用蔑水,但都沒有搞明白邢锯,一方面是網(wǎng)上很少有...
    張晨輝Allen閱讀 2,411評論 0 3
  • 原鏈接:KMP算法詳解|CloudWong 傳統(tǒng)的字符串匹配模式(暴力循環(huán)) 子串的定位操作通常稱作串的串的匹配模...
    簡Cloud閱讀 3,916評論 1 22
  • 數(shù)據(jù)結(jié)構(gòu)與算法--KMP算法查找子字符串 部分內(nèi)容和圖片來自這三篇文章: 這篇文章、這篇文章搀别、還有這篇他們寫得非常...
    sunhaiyu閱讀 1,743評論 1 21
  • 數(shù)據(jù)結(jié)構(gòu) 第8講 KMP算法 講這個算法之前丹擎,我們首先了解幾個概念: 串:又稱字符串,是由零個或多個字符組成的有限...
    rainchxy閱讀 1,310評論 0 3
  • 引言 字符串匹配一直是計算機(jī)科學(xué)領(lǐng)域研究和應(yīng)用的熱門領(lǐng)域,算法的改進(jìn)研究一直是一個十分困難的課題蒂培。作為字符串匹配中...
    潮汐行者閱讀 1,650評論 2 6