亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

快速模式匹配算法(KMP)的深入理解

2020-01-26 16:04:22
字體:
來源:轉載
供稿:網友
恐怕現在用過電腦的人,一定都知道大部分帶文本編輯功能的軟件都有一個快捷鍵ctrl+f 吧(比如word)。這個功能主要來完成“查找”,“替換”和“全部替換”功能的,其實這就是典型的模式匹配的應用,即在文本文件中查找串。

1.模式匹配
模式匹配的模型大概是這樣的:給定兩個字符串變量S和P,其中S成為目標串,其中包含n個字符,P稱為模式串,包含m個字符,其中m<=n。從S的給定位置(通常是S的第一個位置)開始搜索模式P。如果找到,則返回模式P在目標串中的位置(即:P的第一個字符在S中的下標)。如果在目標串S中沒有找到模式串P,則返回-1.這就是模式匹配的定義啦,下面來看看怎么實現模式匹配算法吧。

2.樸素的模式匹配
樸素的模式匹配算法非常簡單,容易理解,大概思路是這樣的:從S的第一個字符S0開始,將P中的字符依次和S中字符比較,若S0=P0 && …… && Sm-1 = Pm-1,則證明匹配成功,剩下的匹配無需進行了,返回下標0。若在某一步Si != Pi 則P中剩下的字符也不用比較了,不可能匹配成功了,然后從S中第二個字符開始與P中第一個字符進行比較,同理,也是知道Sm = Pm-1或者找到某個i使得Si != S-1為止。依次類推若知道以S中第n-m個開始字符為止,還沒有匹配成功則證明S中不存模式P。(想想為什么這里強調是n-m)這個代碼實現應該是非常簡單的,具體開始參考strstr函數的內部實現??梢钥纯窗俣劝倏?,給個鏈接http://baike.baidu.com/view/745156.htm,這里不寫出來了,還得趕緊進入正題KMP呢。

3.快速模式匹配算法(KMP)
樸素的模式匹配效率不高的主要原因是進行了重復的字符比較。下一次比較和上一次比較沒有任何的聯系,是樸素模式匹配的缺點,其實上一次比較的比較結果是可以利用的,這就產生了快速模式匹配。在樸素的模式匹配中,目標串S的下標移動是一步一步的,這其實并不好,移動步數沒有必要為1。
現在不妨假設,當前匹配情況是這樣的:S0 …… St St+1 …… St+j  與 P0 P1…… Pj ,現在正在嘗試匹配的字符是St+j+1和Pj+1,并且St+j+1 != Pj+1,言外之意就是說St St+1……St+j和P0 P1……Pj是完全匹配的。那么這個時候,S中下一次匹配開始位置應該是什么呢??按照樸素的模式匹配,下次比較應該從St+1開始,并且令St+1和P0比較,但是在快速模式匹配中并不是這樣,快速模式匹配選擇St+j+1和Pk+1比較,K是什么呢?K是這樣的一個值,使得P0 P1……Pk 和 Pj-k Pj-k+1……Pj完全匹配,不妨設k=next[j],因此P0 P1……Pk和St+j-k St+j-k+1 ……St+j完全匹配。那么下一次要進行匹配的兩個字符應為St+j+1和Pk+1。S和P都沒有回溯到下標0在進行比較,這就是KMP之所以快的原因啦。
現在關鍵問題來了,這個K怎么能得到呢?如果得到這個K值復雜度高,那這個思路就不好了,其實這個K呢,只和模式串P有關系,并且要求m個k,k = next[j],因此只要算一次存儲到next數組中就可以了,并且時間復雜度和m有關系(線性關系)??纯淳唧w怎么求next數組的值,即求k。
用歸納法求next[]:設next(0) = -1,若已知next(j) = k,欲求得next[j+1]。
(1)如果Pk+1 = Pj+1,顯然next[j+1] = k+1.如果Pk+1 != Pj+1,則next[j+1] < next[j],于是尋找h < k 使得P0 P1……Ph = Pj-h Pj-h+1……Pj = Pk-h Pk-h+1……Pk。也就是說h = next(k);看出來了吧,這是個迭代的過程。(也就是以前的結果對求以后的值有用)
(2)如果不存這樣的h,說明P0 P1……Pj+1中沒有前后相等的子串,因此next[j+1] =-1.
(3)如果存在這樣的h,繼續檢驗Ph和Pj是否相等。知道找到這中相等的情況,或者確定為-1求next[j+1]的過程結束。
看看實現的代碼:
復制代碼 代碼如下:

View Code
int next[20] ={0};
//注意返回結果是一個數組next,保存m個k值得地方,即若next[j]=k
//則str[0]str[1]…str[k] = str[j-k]str[j-k+1]…str[j]
//這樣當des[t+j+1]和pat[j+1]匹配失敗時,下一個匹配位置為des[t+j+1]和next[j]+1
void Next(char str[],int len)
{
    next[0] = -1;
    for(int j = 1 ; j < len ; j++)
    {
        int i = next[j-1];
        while(str[j] != str[i+1] && i >= 0)//迭代的過程
        {
            i = next[i];
        }
        if(str[j] == str[i+1])
        {
            next[j] = i+1;
        }
        else
        {
            next[j] = -1;
        }
    }
}

現在有了next數組保存的k值,就可以實現KMP算法了:
復制代碼 代碼如下:

View Code
//des是目標串,pat是模式串,len1和len2是串的長度
int kmp(char des[],int len1,char pat[],int len2)
{
    Next(str2,len2);
    int p=0,s=0;
    while(p < len2  && s < len1)
    {
        if(pat[p] == des[s])
        {
            p++;s++;
        }
        else
        {
            if(p==0)
            {
                s++;//若第一個字符就匹配失敗,則從des的下一個字符開始
            }
            else
            {
                p = next[p-1]+1;//用失敗函數確定pat應回溯到的字符
            }
        }
    }
    if(p < len2)//整個過程匹配失敗
    {
        return -1;
    }
    return s-len2;
}

時間復雜度:
對于Next函數近似接近O(m),KMP算法的時間復雜度為O(n),所以整個算法的時間復雜度為O(n+m)
空間復雜度:
多引入了O(m)的空間復雜度。
4.應用KMP的一道面試題
給定兩個字符串是s1和s2,要判定s2是否能夠被s1做循環移位得到的字符串包含。例如s1=AABCD,s2 =CDAA,返回true,因為s1循環移位可以變成CDAAB。給定s1=ACBD和s2=ACBD則返回false。
分析:不難發現對s2移位得到的字符串都將是字符串s1s1的子串,如果s2可以有s1循環移位得到,那么s2一定是s1s1的子串,這時KMP算法是不是就很管用了呢。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品视频三区| 九九精品在线视频| 亚洲网站在线看| 亚洲第一精品夜夜躁人人躁| 国产精品91一区| 欧美日韩国产一中文字不卡| 国产精品69久久| 亚洲免费福利视频| 国产精品久久久久久久av电影| 欧美激情视频在线| 456国产精品| 国产欧洲精品视频| 色妞在线综合亚洲欧美| 91亚洲人电影| 91久久精品久久国产性色也91| 美女av一区二区| 欧美亚洲午夜视频在线观看| 欧美性色视频在线| 日本亚洲欧洲色| 中文字幕v亚洲ⅴv天堂| 欧美亚洲一区在线| 91高清免费在线观看| 中文字幕亚洲国产| 精品久久在线播放| 国产精品久久综合av爱欲tv| 国产成人精品久久| 91亚洲精品久久久久久久久久久久| 欧美极品在线视频| 国产一区二区丝袜| 中文字幕亚洲综合久久筱田步美| 精品久久久久久久大神国产| 欧美性在线视频| 日本久久精品视频| 91色p视频在线| 国产69久久精品成人看| 亚洲精品mp4| 久久91亚洲人成电影网站| 欧美成人精品在线播放| 久久久久北条麻妃免费看| 国产精品视频26uuu| 欧美日韩亚洲91| 精品高清一区二区三区| 亚洲午夜精品久久久久久久久久久久| 久久精品成人动漫| 国产精品视频播放| 91视频88av| 日韩精品欧美激情| 国产精品影片在线观看| 日韩美女福利视频| 久青草国产97香蕉在线视频| 91av视频在线| 亚洲人高潮女人毛茸茸| 欧美精品videos| 91产国在线观看动作片喷水| 久久久久久久999| 亚洲大胆人体在线| 国产精品露脸av在线| 韩国19禁主播vip福利视频| 欧美视频一区二区三区…| www.99久久热国产日韩欧美.com| 久久99久久99精品中文字幕| xvideos成人免费中文版| 欧美一级淫片丝袜脚交| 欧美激情一区二区久久久| 91干在线观看| 国产欧美 在线欧美| 日韩av中文在线| 亚洲韩国日本中文字幕| 国产一区二区三区丝袜| 亚洲国产精品一区二区久| 一本一本久久a久久精品牛牛影视| 日韩av中文字幕在线| 激情亚洲一区二区三区四区| 欧美激情一二三| 国产精品日韩在线| 7m精品福利视频导航| 欧美性猛交xxxx乱大交| 欧美色欧美亚洲高清在线视频| 精品久久久久久久久久国产| 日韩av成人在线观看| 日韩电影第一页| 国产精品免费福利| 亚洲韩国欧洲国产日产av| 欧美久久精品午夜青青大伊人| 欧美黑人又粗大| 国产精品一区av| 欧美精品免费看| 国产精品入口福利| 亚洲激情免费观看| 中文在线资源观看视频网站免费不卡| 欧美乱人伦中文字幕在线| 国语自产精品视频在线看| 成人免费网站在线看| 久久亚洲电影天堂| 色无极影院亚洲| www.日韩系列| 国产精品久久久久久av福利软件| 亚洲女人天堂成人av在线| 亚洲欧美三级伦理| 欧美一级大片视频| 国产在线精品一区免费香蕉| 欧美高清视频在线播放| 亚洲黄色在线看| 欧美国产在线视频| 久久久亚洲成人| 久久久久久久久久久91| 欧美精品久久久久a| 久色乳综合思思在线视频| 国产a级全部精品| 欧美激情精品久久久久久免费印度| 亚洲理论片在线观看| 日本19禁啪啪免费观看www| 欧美最猛性xxxxx免费| 68精品国产免费久久久久久婷婷| 久久精品最新地址| 国产精品自拍偷拍| 中文字幕日韩有码| 久久精品欧美视频| 日韩精品亚洲元码| 国产一区二区三区直播精品电影| 91香蕉国产在线观看| 日韩欧美中文在线| 亚洲第一区第一页| 亚洲欧美日韩另类| 日韩欧美a级成人黄色| 蜜臀久久99精品久久久久久宅男| 亚洲va欧美va在线观看| 久久久国产91| 97av在线播放| 国产99视频精品免视看7| 九九热在线精品视频| 欧美日本高清视频| 日韩在线观看免费高清完整版| 国产成人亚洲综合| 欧美三级欧美成人高清www| 亚洲国产精久久久久久| 国内精品久久久久久中文字幕| 成人精品久久久| 欧美日韩美女在线观看| 欧美激情aaaa| 亚洲va欧美va国产综合久久| 伊人一区二区三区久久精品| 日韩电影中文字幕在线观看| 国产亚洲福利一区| 精品国偷自产在线视频99| 国产精品高清在线观看| 亚洲欧美日韩视频一区| 成人免费网站在线观看| 在线播放亚洲激情| 中文在线资源观看视频网站免费不卡| 亚洲福利影片在线| 亚洲午夜未满十八勿入免费观看全集| 久久久久久久国产精品视频| 成人福利视频在线观看| 亚洲欧洲一区二区三区在线观看| 欧美成人精品在线视频| 欧美午夜久久久| 久久久精品视频成人| 欧美精品做受xxx性少妇| 日韩免费观看高清| 国内外成人免费激情在线视频网站| 欧美激情一区二区三级高清视频| 欧美成人免费全部| 清纯唯美亚洲综合|