青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

KMP和擴展KMP

Posted on 2011-04-17 19:11 Mato_No1 閱讀(5837) 評論(2)  編輯 收藏 引用 所屬分類: 字符串匹配
KMP:給出兩個字符串A(稱為模板串)和B(稱為子串),長度分別為lenA和lenB,要求在線性時間內,對于每個A[i](0<=i<lenA),求出A[i]往前和B的前綴匹配的最大匹配長度,記為ex[i](或者說,ex[i]為滿足A[i-z+1..i]==B[0..z-1]的最大的z值)。KMP的主要目的是求B是不是A的子串,以及若是,B在A中所有出現的位置(當ex[i]=lenB時)。
【算法】
設next[i]為滿足B[i-z+1..i]==B[0..z-1]的最大的z值(也就是B的自身匹配)。設目前next[0..lenB-1]與ex[0..i-1]均已求出,要用它們來求ex[i]的值。
根據ex的定義,有A[i-1-ex[i-1]+1..i-1]==B[0..ex[i-1]-1],這時,若有A[i]==B[ex[i-1]],則可以直接得到ex[i]=ex[i-1]+1(因為i-1-ex[i-1]+1即i-ex[i-1],現在由于A[i]==B[ex[i-1]],可得A[i-ex[i-1]..i]==B[0..ex[i-1]],即A[i-ex[i-1]+1-1..i]==B[0..ex[i-1]+1-1],所以ex[i]=ex[i-1]+1)。若A[i]!=B[ex[i-1]]?
設j=next[ex[i-1]-1],則根據next定義得B[ex[i-1]-j..ex[i-1]-1]==B[0..j-1],又因為A[i-ex[i-1]..i-1]==B[0..ex[i-1]-1]得A[i-j..i-1]==B[ex[i-1]-j..ex[i-1]-1],這樣有A[i-j..i-1]==B[0..j-1]!也就是此時只需再比較A[i]與B[j]的值是否相等即可,若相等,可得ex[i]=j+1,若仍不相等,則更新j為next[j-1],繼續比較A[i]與B[j]是否相等……直到A[i]與B[j]相等或直到j==0時,A[i]仍不等于B[j],此時ex[i]=0。邊界:求ex[0]時,初始j(用來代替ex[i-1])為0。
現在還有一個問題,如何求next?顯然next就是以B自身為模板串,B為子串的“自身匹配”,用類似的辦法即可,唯一不同的是next[0]=lenB可以直接得到,求next[1]時,初始j(代替next[i-1])為0。
【核心代碼】
    lenA = strlen(A); lenB = strlen(B);
    next[
0= lenB;
    
int j = 0;
    re2(i, 
1, lenB) {
        
while (j && B[i] != B[j]) j = next[j - 1];
        
if (B[i] == B[j]) j++;
        next[i] 
= j;
    }
    j 
= 0;
    re(i, lenA) {
        
while (j && A[i] != B[j]) j = next[j - 1];
        
if (A[i] == B[j]) j++;
        ex[i] 
= j;
    }
擴展KMP:給出模板串A和子串B,長度分別為lenA和lenB,要求在線性時間內,對于每個A[i](0<=i<lenA),求出A[i..lenA-1]與B的最長公共前綴長度,記為ex[i](或者說,ex[i]為滿足A[i..i+z-1]==B[0..z-1]的最大的z值)。擴展KMP可以用來解決很多字符串問題,如求一個字符串的最長回文子串和最長重復子串。
【算法】
設next[i]為滿足B[i..i+z-1]==B[0..z-1]的最大的z值(也就是B的自身匹配)。設目前next[0..lenB-1]與ex[0..i-1]均已求出,要用它們來求ex[i]的值。
設p為目前A串中匹配到的最遠位置,k為讓其匹配到最遠位置的值(或者說,k是在0<=i0<i的所有i0值中,使i0+ex[i0]-1的值最大的一個,p為這個最大值,即k+ex[k]-1),顯然,p之后的所有位都是未知的,也就是目前還無法知道A[p+1..lenA-1]中的任何一位和B的任何一位是否相等。
根據ex的定義可得,A[k..p]==B[0..p-k],因為i>k,所以又有A[i..p]==B[i-k..p-k],設L=next[i-k],則根據next的定義有B[0..L-1]==B[i-k..i-k+L-1]。考慮i-k+L-1與p-k的關系:
(1)i-k+L-1<p-k,即i+L<=p。這時,由A[i..p]==B[i-k..p-k]可以得到A[i..i+L-1]==B[i-k..i-k+L-1],又因為B[0..L-1]==B[i-k..i-k+L-1]所以A[i..i+L-1]==B[0..L-1],這就說明ex[i]>=L。又由于next的定義可得,A[i+L]必然不等于B[L](否則A[i..i+L]==B[0..L],因為i+L<=p,所以A[i..i+L]==B[i-k..i-k+L],這樣B[0..L]==B[i-k..i-k+L],故next[i-k]的值應為L+1或更大),這樣,可以直接得到ex[i]=L!
(2)i+k-L+1>=p-k,即i+L>p。這時,首先可以知道A[i..p]和B[0..p-i]是相等的(因為A[i..p]==B[i-k..p-k],而i+k-L+1>=p-k,由B[0..L-1]==B[i-k..i-k+L-1]可得B[0..p-i]==B[i-k..p-k],即A[i..p]==B[0..p-i]),然后,對于A[p+1]和B[p-i+1]是否相等,目前是不知道的(因為前面已經說過,p是目前A串中匹配到的最遠位置,在p之后無法知道任何一位的匹配信息),因此,要從A[p+1]與B[p-i+1]開始往后繼續匹配(設j為目前B的匹配位置的下標,一開始j=p-i+1,每次比較A[i+j]與B[j]是否相等,直到不相等或者越界為止,此時的j值就是ex[i]的值)。在這種情況下,p的值必然會得到延伸,因此更新k和p的值。
邊界:ex[0]的值需要預先求出,然后將初始的k設為0,p設為ex[0]-1。
對于求next數組,也是“自身匹配”,類似KMP的方法處理即可。唯一的不同點也在邊界上:可以直接知道next[0]=lenB,next[1]的值預先求出,然后初始k=1,p=ex[1]。

需要嚴重注意的是,在上述的情況(2)中,本該從A[p+1]與B[p-i+1]開始匹配,但是,若p+1<i,也就是p-i+1<0(這種情況是有可能發生的,當ex[i-1]=0,且前面的ex值都沒有延伸到i及以后的時候)的話,需要將A、B的下標都加1(因為此時p必然等于i-2,如果A、B的下標用兩個變量x、y控制的話,x和y都要加1)!!

【核心代碼】
lenA = strlen(A); lenB = strlen(B);
    next[
0= lenB; next[1= lenB - 1;
    re(i, lenB
-1if (B[i] != B[i + 1]) {next[1= i; break;}
    
int j, k = 1, p, L;
    re2(i, 
2, lenB) {
        p 
= k + next[k] - 1; L = next[i - k];
        
if (i + L <= p) next[i] = L; else {
            j 
= p - i + 1;
            
if (j < 0) j = 0;
            
while (i + j < lenB && B[i + j] == B[j]) j++;
            next[i] 
= j; k = i;
        }
    }
    
int minlen = lenA <= lenB ? lenA : lenB; ex[0= minlen;
    re(i, minlen) 
if (A[i] != B[i]) {ex[0= i; break;}
    k 
= 0;
    re2(i, 
1, lenA) {
        p 
= k + ex[k] - 1; L = next[i - k];
        
if (i + L <= p) ex[i] = L; else {
            j 
= p - i + 1;
            
if (j < 0) j = 0;
            
while (i + j < lenA && j < lenB && A[i + j] == B[j]) j++;
            ex[i] 
= j; k = i;
        }
    }
【時間復雜度分析】
在KMP和擴展KMP中,不管是A串還是B串,其匹配位置都是單調遞增的,故總時間復雜度是線性的,都為O(lenA + lenB)(只是擴展KMP比KMP的常數更大一些)。
【應用】
KMP和擴展KMP在解決字符串問題中有大用。很多看上去很猥瑣的字符串問題,都可以歸結到這兩種算法之中。另外,這里的“字符串”可以延伸為一切類型的數組,而不僅僅是字符數組。

Feedback

# re: KMP和擴展KMP  回復  更多評論   

2011-12-14 22:34 by ~~
KMP算法里面next[0]應該是0才對吧?
next[i]為滿足B[i-z+1..i]==B[0..z-1]的最大的z值(也就是B的自身匹配)
對于B[0],i- 1是-1,不能向前延伸了~

# re: KMP和擴展KMP  回復  更多評論   

2015-08-02 14:21 by yajun
擴展KMP
if (i + L <= p) ex[i] = L; else {
相等的時候,需要向后匹配,因為可能會比L更長。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久国产精品99精品国产| 亚洲精品视频中文字幕| 欧美电影打屁股sp| 99精品国产一区二区青青牛奶| 亚洲天堂成人在线观看| 伊人激情综合| 国产麻豆精品在线观看| 亚洲国产精品一区二区三区| 亚洲一区国产精品| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲国产毛片完整版| 亚洲国产一二三| 亚洲午夜高清视频| 久久理论片午夜琪琪电影网| 欧美三级资源在线| 一色屋精品视频免费看| 一区二区三区国产在线观看| 久久久久久午夜| 亚洲日韩视频| 久久成人精品无人区| 欧美精品www| 国产综合久久| 一区二区三区视频在线观看| 麻豆久久婷婷| 亚洲欧美久久久| 欧美精品情趣视频| 在线观看日韩国产| 欧美主播一区二区三区美女 久久精品人 | 久久久不卡网国产精品一区| 欧美日韩一级大片网址| 在线成人免费观看| 欧美在线播放高清精品| 亚洲精品国产视频| 免费欧美电影| 亚洲国产精品久久久久婷婷884| 欧美一级视频一区二区| 一本色道88久久加勒比精品| 欧美另类在线观看| 亚洲精品黄网在线观看| 免费视频久久| 久久精品视频播放| 国产精品一级二级三级| 欧美国产乱视频| 国产综合色一区二区三区| 亚洲欧美日韩在线| 亚洲精品一二| 欧美日韩精品免费观看| 亚洲精品欧美日韩专区| 亚洲第一福利在线观看| 久久综合色播五月| 亚洲高清视频一区二区| 麻豆精品国产91久久久久久| 久久久久久久精| 激情欧美一区二区三区在线观看| 欧美在线看片| 久久国产一区二区三区| 国产亚洲精品一区二区| 久久精品亚洲| 久久久久久久久久久久久女国产乱| 韩国欧美国产1区| 欧美大片免费| 欧美国产视频在线观看| 一区二区三区日韩欧美精品| 洋洋av久久久久久久一区| 欧美午夜欧美| 欧美一级电影久久| 欧美综合国产| 最新亚洲一区| 99视频在线观看一区三区| 欧美午夜久久久| 久久久国产精品一区二区中文| 久久精品国产免费观看| 亚洲激情中文1区| 日韩午夜电影在线观看| 国产精品黄色在线观看| 久久久久久一区| 欧美肥婆bbw| 亚洲欧美文学| 久久夜色精品国产欧美乱极品| 亚洲激情精品| 亚洲天堂免费在线观看视频| 国产一区二区三区在线观看免费 | 亚洲成人在线网| 91久久嫩草影院一区二区| 免费观看30秒视频久久| 欧美精品自拍偷拍动漫精品| 午夜在线视频观看日韩17c| 亚洲欧美另类久久久精品2019| 极品尤物久久久av免费看| 亚洲人成亚洲人成在线观看| 国产精品盗摄久久久| 麻豆精品网站| 欧美色另类天堂2015| 久久精品人人做人人爽| 老鸭窝91久久精品色噜噜导演| 亚洲香蕉伊综合在人在线视看| 亚洲一二三区在线观看| 亚洲国产精彩中文乱码av在线播放 | 狠狠色丁香久久综合频道| 日韩一级在线| 一区二区三区久久网| 国产一区日韩二区欧美三区| 欧美激情亚洲视频| 国产精品免费在线 | 日韩视频在线播放| 影音先锋国产精品| 亚洲性图久久| 9色porny自拍视频一区二区| 久久久一区二区三区| 久久精品一区二区国产| 欧美午夜影院| 亚洲精品久久久久久久久久久| 在线精品亚洲| 欧美在线地址| 午夜欧美精品| 欧美性久久久| 亚洲乱码日产精品bd| 亚洲精品四区| 免费观看久久久4p| 美女诱惑黄网站一区| 极品av少妇一区二区| 先锋a资源在线看亚洲| 欧美一级理论片| 国产麻豆日韩欧美久久| 亚洲欧美一区二区原创| 亚洲一区高清| 国产精品美女久久福利网站| 一本一本久久| 亚洲天堂av在线免费| 欧美视频在线不卡| 国产精品99久久久久久www| 亚洲视频1区2区| 欧美亚洲成人网| 国产精品99久久久久久久女警| 一本色道精品久久一区二区三区| 欧美成人69| 亚洲精品免费网站| 中文日韩在线| 国产精品亚洲美女av网站| 午夜日韩激情| 欧美成人午夜激情在线| 亚洲精品美女久久久久| 欧美人与性禽动交情品| 一区二区三区高清在线观看| 亚洲欧美精品| 国产美女精品一区二区三区| 欧美一站二站| 欧美77777| 9人人澡人人爽人人精品| 国产精品盗摄久久久| 欧美在线视频播放| 亚洲第一福利在线观看| 一区二区三区四区国产精品| 国产精品毛片a∨一区二区三区| 亚洲欧美经典视频| 免费久久99精品国产自| 99v久久综合狠狠综合久久| 欧美新色视频| 久久国产精品黑丝| 亚洲欧洲在线播放| 欧美一区二区三区久久精品茉莉花| 国产午夜精品久久| 欧美成人午夜| 午夜伦欧美伦电影理论片| 亚洲福利视频一区二区| 亚洲欧美日本精品| ●精品国产综合乱码久久久久| 欧美日韩成人综合| 亚洲电影欧美电影有声小说| 中国女人久久久| 狠狠狠色丁香婷婷综合激情| 欧美日韩国产精品自在自线| 久久九九有精品国产23| 一本色道久久88亚洲综合88| 久久综合成人精品亚洲另类欧美| 日韩午夜激情av| 狠狠色综合色综合网络| 欧美性片在线观看| 欧美第一黄网免费网站| 久久av资源网| 亚洲视频一区二区| 欧美激情bt| 老司机午夜精品视频| 香蕉乱码成人久久天堂爱免费| 亚洲黄网站在线观看| 国产一区高清视频| 国产精品久久久一本精品| 欧美大片va欧美在线播放| 欧美综合二区| 欧美亚洲免费电影| 亚洲视频在线观看三级| 亚洲欧洲在线一区| 欧美成人久久| 欧美va亚洲va香蕉在线| 久久青草福利网站| 久久精品国产欧美亚洲人人爽| 亚洲男女毛片无遮挡| 亚洲性感美女99在线| 99综合精品| 亚洲一区二区三区涩|