KMP算法

KMP算法

與BF算法相比,KMP的改進(jìn)之處在于圣蝎,當(dāng)主串當(dāng)前指針(下標(biāo))字符與模式串當(dāng)前指針(下標(biāo))字符不相等時(shí)刃宵,主串的指針i不需要回溯,而是利用已經(jīng)得到的"部分匹配"的結(jié)果徘公,將模式串盡量的右移牲证,繼續(xù)進(jìn)行匹配!

注:統(tǒng)一关面,本篇討論的字符串的下標(biāo)都是從0開始的

例如:


主串的i指針無需回溯到7坦袍,而是保持不動(dòng),此時(shí)i = 12j = 6不匹配等太,利用已"部分匹配"的模式串部分 ABCDAB 將整個(gè)模式串盡量右移捂齐。
可以發(fā)現(xiàn)已部分匹配的模式串部分 ABCDAB 最長公共前后綴為AB,右移的最大距離即前綴部分后綴部分重疊

可見此時(shí)j(下標(biāo)值)即為之前j = 6時(shí),其前面部分匹配串的最長公共前后綴;
Next數(shù)組保存當(dāng)前字符前的部分串(不包含當(dāng)前字符)的最長公共前后綴的大小
如上栗中榴都,next[6] = 2

Next數(shù)組
注:如何理解 j = 0 時(shí)拴驮,next[0] = -1?

失配于模式串首字符流程
KMP算法Code框架 : 按以上定義實(shí)現(xiàn)(Next[]構(gòu)建下面分析)
/*
@ Author : z
@ Date : 2018.7.30
@ Title : KMP
@ In : str      主串
       substr   模式串
@ Out : 
*/
#include <string>
int  KMP(string str, string substr)
{
    1. 創(chuàng)建模式串substr的next[ ] 數(shù)組
    int * next = BuildNext(substr);    

    int str_len = str.length();
    int substr_len = substr.length();
    int i = 0;      //主串下標(biāo)指針
    int j = 0;      //模式串下標(biāo)指針

    while (i < str_len && j < substr_len)
    {
        if ( (0 > j)  || ( str[i] == substr[j]) )
        {     通配符匹配或字符匹配
            i ++唆鸡;
            j ++;       // 攜手共進(jìn)
        }
        else
        {  失配,模式串盡量右移,即指針 j 左移 = next[j] 逗旁, i 不變
            j = next[j];
        }
    }// end_while

    delete []next;    //釋放next[]數(shù)組

    return i-j;     //  >= 0英古,匹配成功,且返回主串中模式串位置
                    //  < 0 , 匹配失敗
}

Key:關(guān)鍵在于模式串next[]數(shù)組的構(gòu)建,下面介紹!!藐石!


根據(jù)上面 Next數(shù)組 的定義實(shí)現(xiàn) next[ ]表的構(gòu)造
利用遞推來構(gòu)造 next[ ]青自,以下:
已知 next[ j ] 的值雷滚,如何高效計(jì)算 next[ j + 1 ]
注 : 嚴(yán)格按定義商源,肯定能實(shí)現(xiàn)出爹,重點(diǎn)在于理解梢为!
next[ ]構(gòu)建Code
@ Author : zzz
@ Date   : 2018.7.30
@ Title  : Build next
@ In     : str   字符串
@ Out    : 

#include <string>

int * BuildNext(string str)
{
    int len = str.length();
    int j = 0;           // "主"串指針

    int * Next = new int[len];   // Next[] 表

/************************************************************/
    # 初始化 Next[0] = -1,
    # str[-1]作為通配符粟害,此處 t 可視為記錄:最大公共前后綴的長度
/************************************************************/
    int t = Next[0] = -1;

    while ( j < len-1)
    {
        if ((0 > t) || (str[j] == str[t]))
        {//哨兵匹配 即 t = -1 或 字符匹配
            Next[++j] = ++t;
        }
        else
        {//失配 , 遞推!!!
            t = Next[t] ;      
        }
    }

    return Next;
}
分析上面代碼中循環(huán)中的 ifelse
  • if ((0 > t) || (str[j] == str[t]))是分析中的情況1,next[j+1] = next[j] + 1,next[j]用 t 記錄

  • else : t = Next[t]

舉個(gè)栗子恰聘,展示Next[]數(shù)組的構(gòu)建過程
依此類推

else的遞推過程
KMP - Next[ ] 數(shù)組的優(yōu)化

反例

改進(jìn) Next[ ] Code
@ Author : zzz
@ Date   : 2018.7.30
@ Title  : 改進(jìn)Next
@ In     : str字符串
@ Out    : 

#include <string>

int * BuildNext(string str)
{
    int len = str.length();
    int j = 0;           // "主"串指針

    int * Next = new int[len];   // Next[] 表

/************************************************************/
    # 初始化 Next[0] = -1,
    # str[-1]作為通配符排作,此處 t 可視為記錄:最大公共前后綴的長度
    # t 也可視為模式串指針,大小為最大公共前后綴的長度
/************************************************************/
    int t = Next[0] = -1;

    while ( j < len-1)
    {
        if ((0 > t) || (str[j] == str[t]))
        {// 匹配 , 改進(jìn)處!!!
            j ++;
            t ++;
            Next[j] = ( str[j] != str[t] ? t : Next[t] );            // !!! !!!
        }
        else
        {//失配 
            t = Next[t] ;      
        }
    }

    return Next;
}
改進(jìn)Next數(shù)組構(gòu)建,遞推的過程!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末安拟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖蕴纳,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稻薇,死亡現(xiàn)場(chǎng)離奇詭異忱屑,居然都是意外死亡从铲,警方通過查閱死者的電腦和手機(jī)伸辟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人大州,你說我怎么就攤上這事娃豹。” “怎么了嚷缭?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵砰识,是天一觀的道長频蛔。 經(jīng)常有香客問我,道長三圆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上剂府,老公的妹妹穿的比我還像新娘。我一直安慰自己闰歪,他們只是感情好饱亿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著淑翼,像睡著了一般凡伊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窒舟,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天系忙,我揣著相機(jī)與錄音,去河邊找鬼惠豺。 笑死银还,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的洁墙。 我是一名探鬼主播蛹疯,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼热监!你這毒婦竟也來了捺弦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎列吼,沒想到半個(gè)月后幽崩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寞钥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年慌申,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片理郑。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蹄溉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出您炉,到底是詐尸還是另有隱情柒爵,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布赚爵,位于F島的核電站棉胀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏囱晴。R本人自食惡果不足惜膏蚓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一瓢谢、第九天 我趴在偏房一處隱蔽的房頂上張望畸写。 院中可真熱鬧,春花似錦氓扛、人聲如沸枯芬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽千所。三九已至,卻和暖如春蒜埋,著一層夾襖步出監(jiān)牢的瞬間淫痰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工整份, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留待错,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓烈评,卻偏偏與公主長得像火俄,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子讲冠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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

  • 數(shù)據(jù)結(jié)構(gòu)與算法--KMP算法查找子字符串 部分內(nèi)容和圖片來自這三篇文章: 這篇文章瓜客、這篇文章、還有這篇他們寫得非常...
    sunhaiyu閱讀 1,735評(píng)論 1 21
  • 參考文章 知乎:如何更好的理解和掌握 KMP 算法?從頭到尾徹底理解KMPKMP 算法(1):如何理解 KMP(原...
    Mjolnir1107閱讀 985評(píng)論 0 0
  • 一、定義 KMP(Knuth-Morris-Pratt)算法谱仪,其實(shí)是對(duì)暴力查找算法的優(yōu)化玻熙。在暴力查找算法中,用于追...
    null12閱讀 824評(píng)論 0 0
  • 文章大綱:1.KMP算法概念2.KMP算法中最核心的next[] 數(shù)組是如何生成的3.使用KMP算法 匹配字符串 ...
    檸檬烏冬面閱讀 815評(píng)論 0 3
  • 轉(zhuǎn)載請(qǐng)注明出處: KMP算法及優(yōu)化 今天看到同學(xué)在復(fù)習(xí)數(shù)據(jù)結(jié)構(gòu)書上的KMP算法芽卿,忽然發(fā)覺自己又把KMP算法忘掉了揭芍,...
    瘋狂的愛因斯坦閱讀 1,826評(píng)論 1 7