日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2020年最全最简单KMP算法讲解

發(fā)布時(shí)間:2024/10/14 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020年最全最简单KMP算法讲解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄
1.KMP算法的來源
2.最大公共前后綴
3.KMP算法原理
4.next數(shù)組
5.next數(shù)組值的確定
6.KMP算法的缺陷
7.KMP算法的改進(jìn)

1.KMP算法的來源

其實(shí)博主剛看KMP算法的時(shí)候的反應(yīng)是這樣的:

我們引用一個(gè)問題

給定一個(gè)主串S及一個(gè)模式串P,判斷模式串是否為主串的子串;若是,返回匹配的第一個(gè)元素的位置(序號(hào)從1開始),否則返回0;如S=“abcd”,P=“bcd”,則返回2;S=“abcd”,P=“acb”,返回0

這道題我們最先想到的算法設(shè)計(jì)思路肯定和下面動(dòng)圖差不多


我們想到這個(gè)思路后,直接兩層for循環(huán)輕松解決,雖然這種樸素算法思路簡(jiǎn)單而且容易想到,但兩個(gè)串都有依次遍歷,時(shí)間復(fù)雜度為O(n*m),效率不高,那么為了讓效率變高,我們的KMP算法橫空出世

2.最大真公共前后綴

在正式介紹KMP算法之前我們了解一個(gè)概念,一會(huì)KMP算法要用到,那就是最大公共前后綴,首先我們介紹前綴后綴

真前綴:就是包含第一個(gè)字符但不包含最后一個(gè)字符的連續(xù)子串
真后綴:就是包含最后一個(gè)字符但不包含第一個(gè)字符的連續(xù)子串

我們舉個(gè)例子,列出串a(chǎn)bcab的所有真前綴后綴
前綴有:

  • a
  • ab
  • abc
  • abca
  • 后綴有:

  • b
  • ab
  • cba
  • bcab
  • 真公共前后綴:一個(gè)字符串前綴和后綴相同的的字符串
    最大真公共前后綴:一個(gè)字符串前綴和后綴相同的最大長(zhǎng)度所代表的字符串

    對(duì)于abcab來說,公共前后綴只有ab,那么最大公共前后綴為ab

    3.KMP算法的原理

    樸素算法中,P的第j位失配,默認(rèn)的把P串后移一位。但在前一輪的比較中,我們已經(jīng)知道了P的前(j-1)位與S中間對(duì)應(yīng)的某(j-1)個(gè)元素已經(jīng)匹配成功了。就意味著,在一輪的嘗試匹配中,我們get到了主串的部分內(nèi)容我們能否利用這些內(nèi)容,讓P多移幾位(我認(rèn)為這就是KMP算法最根本的東西),減少遍歷的趟數(shù)呢?答案是肯定的。再看下面改進(jìn)后的動(dòng)圖就是我們KMP算法的匹配過程:

    首先我們根據(jù)上面的KMP匹配模式圖的規(guī)律與樸素的算法做一個(gè)對(duì)比:

    樸素算法: 每次失配,S串的索引i定位的本次嘗試匹配的第一個(gè)字符的后一個(gè)。P串的索引j定位到1,T(n)=O(n*m)
    KMP算法: 每次失配,S串的索引i不動(dòng),P串的索引j定位到某個(gè)數(shù)。T(n)=O(n+m),時(shí)間效率明顯提高

    再看一組KMP算法一次移動(dòng)圖解(相同顏色代表相同的字符),初始位置如下:

    下一步:


    你會(huì)發(fā)現(xiàn)它與樸素的算法有兩個(gè)區(qū)別:

  • 樸素的算法主串指針i會(huì)跳到第三個(gè)位置,而KMP算法跳到第九個(gè)位置
  • 樸素的算法模式串指針j會(huì)從第一個(gè)字符重新匹配,而KMP算法直接讓j在第四個(gè)字符和主串的i指針指向的字符進(jìn)行比較
  • 再重新看看這一句話

    KMP算法: 每次失配,S串的索引i不動(dòng),P串的索引j定位到某個(gè)數(shù)。T(n)=O(n+m),時(shí)間效率明顯提高

    那么我們究竟能在前一輪失敗的匹配結(jié)果里邊得到什么內(nèi)容,能讓S串的索引i不動(dòng),P串的索引j定位到某個(gè)數(shù)呢?

    這時(shí)候就要借助我們的最大真公共前后綴了:在上面的兩張圖中,第一張圖的匹配失敗是在模式串的第八個(gè)位置,也就是前七個(gè)位置都匹配成功,我們根本就不需要再用樸素的匹配方式把主串的匹配指針往后移動(dòng)一位把模式串的匹配指針重新指向第一個(gè)字符。因?yàn)?font color="red">模式串再往右移動(dòng),只有我們主串的這七個(gè)字符的后綴和模式串這七個(gè)字符的前綴(也就是這七個(gè)字符的公共前后綴)才能完全重合,其他的都不能完全重合,這就是我們找尋真公共前后綴的意義,真公共前后綴必須是最大的,否則我們往往會(huì)錯(cuò)過最佳結(jié)果,可以自己找一個(gè)例子試一試,博主就不再深究了,這樣就可以保證指向我們主串的指針不發(fā)生回溯,即主串的i指針之后往后移動(dòng),不會(huì)往前移動(dòng)

    4.next數(shù)組

    為了表示下一輪比較模式串j定位的地方,我們將其定義為next[j],next[j]就是第j個(gè)元素前j-1個(gè)元素最大真公共前后綴所代表字符串的長(zhǎng)度個(gè)數(shù)加1(加1的目的是直接匹配最大公共前后綴的下一位)

    針對(duì)上面的兩張動(dòng)圖,我們可以看出前j-1最大真公共前后綴為3,加1就是4,那么下一輪匹配就從第4個(gè)字符開始,所有對(duì)于上面的那個(gè)動(dòng)圖,模式串第8位的next數(shù)組值為4即next[8]=4;

    也就是說只要我們確定一個(gè)模式串所有字符的next數(shù)組值,那么就知道了下一次我們模式串匹配所要匹配的初始位置即當(dāng)發(fā)生失配時(shí),i不變,j=next[j]就好啦!接下來就是怎么確定next值了。

    那么我們手寫一個(gè)next數(shù)組值,如下面動(dòng)圖(首尾重合個(gè)數(shù)就是我們的最大真公共前后綴):

    我們規(guī)定next[1]=0


    也就是說:

    5.next數(shù)組值的確定

    雖然我們可以看出來某一個(gè)字符串的最大真公共前后綴,但是程序是不能看出來的,要按照某些規(guī)律進(jìn)行推理,那么按照何種規(guī)律呢?

    首先我們可以從前面的圖中推理出next[j+1]的最大值為next[j]+1

    為啥呢,我們舉個(gè)例子:

    1.下圖中我們已知next[16]=8,我們來推理next[17]的值;

    2.如果P8=P16,則明顯next[17]=8+1=9(也就是我們所說的next[j+1]的最大值為next[j]+1),可能會(huì)有疑問了,如果 P8!=P16該咋推導(dǎo)呢,不急我們一步一步來,如果next[8]=4,即:

    3.再加上已知next[16]=8,那么我們就可以得出如圖:

    4.那么我們證明這四部分相等得到意義其實(shí)就是為了證明如圖

    5.現(xiàn)在在判斷,如果P16=P4則next[17]=4+1=5,否則,在繼續(xù)遞推,若next[4]=2,那么有下圖關(guān)系:

    6.若P16=P2,則next[17]=2+1=3;否則繼續(xù)取next[2]=1、next[1]=0;遇到0時(shí)還沒出結(jié)果,則遞推結(jié)束,此時(shí)next[17]=1

    也就是說我們求j的next[j]的值,其實(shí)就是前j-1個(gè)字符的next的數(shù)組值一步一步按照上述方法地推得到

    7.求一個(gè)字符串的next數(shù)組值得代碼實(shí)現(xiàn)(仔細(xì)品完上圖再看)

    void get_next(char T[],int next[]) {int i=1;int j=0;next[1]=0;while(i<T[0])//T[0]為字符串長(zhǎng)度{if(j==0||T[i]==T[j])//T[i]表示后綴的單個(gè)字符,T[j]表示前綴的單個(gè)字符 {i++;j++;next[i]=j; }elsej=next[j];//若字符不相同那么j值回溯 } }

    6.KMP算法的缺陷

    KMP算法的改進(jìn)(臥槽還這么nb的算法還有缺陷?我tm:"…"(虎狼之詞))

    比如我們的主串是S="aaaabcde",模式串是P="aaaaax"那么模式串的next數(shù)組值我們可以很快寫出(自己寫一遍)是012345,我們的KMP算法是這么匹配的:

    我們觀眾老爺人均月收入十萬肯定隨便都看得出來,博主看了好一會(huì)

    我們可以看出第一步失配的時(shí)候是在第五個(gè)位置,失配的字符為a,那么此時(shí)第二步KMP算法是跳到第五個(gè)字符的next數(shù)組值(next[5]=4)里進(jìn)行匹配,但是模式串第四個(gè)字符還是a,上一個(gè)a都已經(jīng)匹配失敗了,這一個(gè)a肯定也是失敗,換句話來說,這個(gè)匹配就是多余的,我們看之后KMP的好幾步都是a與主串第一次失配的b進(jìn)行匹配,所以這幾步都是多余的,這就是KMP算法的缺陷

    7.KMP算法的改進(jìn)

    其實(shí)挺簡(jiǎn)單,就是加一步當(dāng)前模式串失配的字符和next數(shù)組對(duì)應(yīng)位置的字符進(jìn)行比較一次,如果相同那么直接再進(jìn)行一次j=next[j]不相同就再次進(jìn)行模式串和主串的匹配

    我們把改進(jìn)后的數(shù)組名稱為nextval,我們簡(jiǎn)單推導(dǎo)一下nextval的數(shù)組各個(gè)值得確定過程

    比如模式串為T="abab"

    失配位置next數(shù)組值分析netival數(shù)組值
    第一個(gè)字符anext[1]=0默認(rèn)的第一個(gè)字符的nextval的字符為0nextval[1]=0
    第二個(gè)字符bnext[2]=1模式串失配時(shí)的字符為b,next表示的下一個(gè)匹配字符為a,不相同所以和next[2]值相同nextval[2]=1
    第三個(gè)字符anext[3]=1模式串失配時(shí)的字符為a,next表示的下一個(gè)匹配字符也是a,相同所以不需要再次比較,所以就需要地推一下發(fā)現(xiàn)當(dāng)nextval[3]=nextval[1]=0的時(shí)候,才需要進(jìn)行下次匹配,等于0就是主串的匹配指針右移動(dòng)一位nextva[3]=0
    第四個(gè)字符bnext[4]=2由于模式串失配位置為b,next數(shù)組指向的下一個(gè)匹配字符也是b,所以需要我們進(jìn)一步遞推,當(dāng)netival[4]=netival[2]=1的時(shí)候,此時(shí)下一輪匹配的字符是a不是b所以可以進(jìn)行下一輪的匹配nextval[4]=1

    其實(shí)和next數(shù)組差不多,nextval數(shù)組索引大的值可以被nextval數(shù)組索引小的值推導(dǎo)出來

    代碼實(shí)現(xiàn):

    void get_nextval(char T[],int nextval[]) {int i=1;int j=0;nextval[1]=0;while(i<T[0])//T[0]為字符串長(zhǎng)度{if(j==0||T[i]==T[j])//T[i]表示后綴的單個(gè)字符,T[j]表示前綴的單個(gè)字符 {i++;j++;if(T[i]!=T[j])nextval[i]=j;elsenextval[i]=nextval[j]; }elsej=nextval[j];//若字符不相同那么j值回溯 } }

    參考博客:https://blog.csdn.net/qq_37969433/article/details/82947411

    總結(jié)

    以上是生活随笔為你收集整理的2020年最全最简单KMP算法讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 伊人欧美| 免费看一级片 | 亚洲高清视频一区二区 | 免费毛片在线播放免费 | 久久五 | 蜜桃视频日韩 | 91香蕉国产在线观看软件 | av在线亚洲天堂 | 成人午夜影院在线观看 | 亚洲天堂男人天堂 | 女性向av免费网站 | 香蕉视频官网在线观看 | 神马三级我不卡 | 日批动态图 | 日日干日日射 | 成人av专区 | 永久免费在线视频 | 国产精品久久久久毛片大屁完整版 | 麻豆蜜桃在线观看 | 欧美影视 | 成人免费高清在线播放 | 国产盗摄在线观看 | 亚洲奶汁xxxx哺乳期 | 色哟哟视频网站 | 日本少妇喷水视频 | 国产全是老熟女太爽了 | 久久综合五月天 | 一区二区在线观看免费视频 | 成人精品一区二区三区电影黑人 | 欧美一级片a | 亚洲 欧美 日韩 综合 | 精品无码在线观看 | 日本一区二区在线不卡 | 老熟妇高潮一区二区三区 | 一区二区视频在线观看免费 | 欧美黄色一级大片 | 国产伦一区二区 | 日韩a在线观看 | 久久青青热 | 少妇熟女一区二区三区 | 亚洲国产精品久久久久爰色欲 | 国产夫妇交换聚会群4p | 色狠狠一区二区 | 成人av高清 | 好吊一区二区三区视频 | 午夜精品偷拍 | 日本一区电影 | 国产色播av在线 | 波多野结衣在线 | 日韩av在线免费播放 | 国产精品果冻传媒潘 | 亚州精品国产精品乱码不99按摩 | 成人区人妻精品一区二区网站 | 日韩精品一区二区三区在线观看 | 天堂av在线网 | 97日韩精品 | 欧美激情视频一区 | 涩涩亚洲 | 五月激情小说网 | 男人资源网站 | 一区二区三区资源 | 亚洲伦理一区二区三区 | 97国产精品视频 | 好看的国产精品 | 成人99视频| www日| 欧美成人免费在线视频 | 欧美三级在线视频 | 国产a线| 中文字幕理伦片免费看 | 巨胸喷奶水www久久久免费动漫 | 亚洲一区二区色 | 欧美日韩首页 | 色女生影院 | 久久精品一区二区国产 | 亚洲天堂三区 | 爱情岛成人| 青青操av在线 | 800av免费在线观看 | 亚洲精品高清在线 | 国产精品亚洲第一 | 香蕉综合网 | 天堂а√在线中文在线新版 | 在线免费观看黄色 | 久久大胆人体 | 亚洲电影在线看 | 欧美日韩高清在线 | 美女张开腿让男人桶爽 | 欧美视频三区 | 久久福利在线 | 成人av手机在线观看 | 亚洲美女中文字幕 | 国产成人精品亚洲男人的天堂 | 亚洲精品人 | av片观看| 色女人在线 | 成人妇女淫片aaaa视频 | 二区三区视频 | 日韩欧美在线一区二区三区 |