最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++ KMP字符串匹配算法

 更新時(shí)間:2022年01月11日 08:38:32   作者:按時(shí)吃早飯的ju  
大家好,本篇文章主要講的是c++ KMP字符串匹配算法,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下

KMP算法簡(jiǎn)介

        KMP算法(Knuth-Morris-Pratt 算法)是一個(gè)著名的字符串匹配算法,它主要的思想是當(dāng)出現(xiàn)字符串不匹配時(shí),可以知道一部分之前已經(jīng)匹配的文本內(nèi)容,可以利用這些信息避免從頭再去做匹配。

        本章以力扣 28. 實(shí)現(xiàn) strStr()為例子進(jìn)行講解。

        力扣28.實(shí)現(xiàn)strStr()函數(shù):給你兩個(gè)字符串 haystack 和 needle ,請(qǐng)你在 haystack 字符串中找出 needle 字符串出現(xiàn)的第一個(gè)位置(下標(biāo)從 0 開(kāi)始)。如果不存在,則返回  -1 。

        說(shuō)明:當(dāng) needle 是空字符串時(shí),我們應(yīng)當(dāng)返回什么值呢?這是一個(gè)在面試中很好的問(wèn)題。對(duì)于本題而言,當(dāng) needle 是空字符串時(shí)我們應(yīng)當(dāng)返回 0 。

        示例 1: 輸入:haystack = "hello", needle = "ll"        輸出:2

  此題若用暴力解法代碼如下:

class Solution {
public:
    int strStr(string haystack, string needle) {
        int n=haystack.size(),m=needle.size();
        if(m==0) return 0;
        for(int i=0;i<n;i++){
            if(haystack[i]==needle[0]){
                for(int j=0;j<m;j++){
                    if(haystack[i+j]!=needle[j])
                        break;
                    if(j==m-1) return i;
                }
            }
        }
        return -1;
    }
};

         可見(jiàn)暴力匹配過(guò)程中實(shí)現(xiàn)的是一個(gè)雙層循環(huán),那么算法的時(shí)間復(fù)雜度較高,為О(n*m),然而KMP的算法時(shí)間復(fù)雜度僅為О(n+m),其算法性能明顯提高,具體時(shí)間復(fù)雜度計(jì)算方法后面介紹。

前綴表

        KMP算法中一個(gè)重要的概念就是前綴表(prefix table),并用一維數(shù)組 next 記錄前綴信息實(shí)際上next數(shù)組就是一個(gè)前綴表。

        了解前綴表我們首先需要了解前綴和后綴的區(qū)別,此處的前綴是指不包含最后一個(gè)字符的所有以第一個(gè)字符開(kāi)頭的連續(xù)子串,后綴是指不包含第一個(gè)字符的所有以最后一個(gè)字符結(jié)尾的連續(xù)子串。比如字符串“abac”的前綴有“a”, "ab”, "aba”,字符串“abac”的后綴有“c”,"ac”,"bac”。

        前綴表第 i 個(gè)位置存的值 next[i] 代表[0,i]這個(gè)字符串最長(zhǎng)的相同前后綴的長(zhǎng)度,比如字符串“abbc”的 next[3]為 0 ,next[2]為 1 ("aba”的前綴有“a”, "ab”,后綴有“a”,"ba”)。

        前綴表的作用是用來(lái)記錄了模板串與主串(文本串)不匹配的時(shí)候,模板串應(yīng)該從哪里開(kāi)始重新匹配。

        KMP算法的核心思想就是先求出匹配模板的next數(shù)組,再運(yùn)用next數(shù)組進(jìn)行字符串匹配。  

如何構(gòu)造前綴表next數(shù)組

void get_next(int *next,string t){ //t為模板字符串
        //定義兩個(gè)指針prefix和suffix,prefix指向前綴起始位置,suffix指向后綴起始位置
        int prefix=0;
        next[prefix]=0;
        for(int suffix=1;suffix<t.size();suffix++){
            while(prefix>0 && t[suffix]!=t[prefix]){//前后綴不相同,前綴指針向前回退
                prefix=next[prefix-1];
            }
            if(t[suffix]==t[prefix]){//前后綴相同,前綴指針前進(jìn)一位
                prefix++; 
            }
            next[suffix]=prefix;//更新next數(shù)組,prefix走到哪說(shuō)明就有多少的相同的前后綴
        }
    }

如何用next數(shù)組進(jìn)行模板匹配

int strStr(string haystack, string needle) {
        if(needle.size()==0) return 0;
        int next[needle.size()];
        get_next(next,needle);
        int j=0;
        //定義兩個(gè)下標(biāo)j指向模版串起始位置,i指向文本串起始位置
        for(int i=0;i<haystack.size();i++){
            while(j>0 && haystack[i]!=needle[j]){ //模版串j位置和文本串i位置不相同,j利用next數(shù)組回退到上一個(gè)相同的位置繼續(xù)匹配
                j=next[j-1];
            }
            if(haystack[i]==needle[j]){  //模版串j位置和文本串i位置相同
                j++;
            }
            if(j==needle.size()){  //找到匹配的字符串
                return (i-needle.size()+1); //返回匹配的字符串起始位置
            }
        }
        return -1;
    }

由此可見(jiàn)構(gòu)造next數(shù)組的時(shí)間復(fù)雜度是О(m),利用next數(shù)組進(jìn)行匹配的時(shí)間復(fù)雜度是О(n),總的時(shí)間復(fù)雜度是О(n+m)

總結(jié)

到此這篇關(guān)于c++ KMP字符串匹配算法的文章就介紹到這了,更多相關(guān)c++ KMP字符串匹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QSS樣式表實(shí)現(xiàn)界面換膚功能

    QSS樣式表實(shí)現(xiàn)界面換膚功能

    這篇文章主要介紹了QSS樣式表實(shí)現(xiàn)界面換膚功能,對(duì)QSS樣式表進(jìn)行簡(jiǎn)單介紹,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • C++實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    C++實(shí)現(xiàn)學(xué)生選課系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)學(xué)生選課系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 可能是你看過(guò)最全的十大排序算法詳解(完整版代碼)

    可能是你看過(guò)最全的十大排序算法詳解(完整版代碼)

    排序算法是程序中常用的算法,下面這篇文章主要給大家介紹了關(guān)于十大排序算法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • C++繼承與菱形繼承詳細(xì)介紹

    C++繼承與菱形繼承詳細(xì)介紹

    繼承(inheritance)機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類(lèi)特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生新的類(lèi),稱派生類(lèi)。繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu),體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程
    2022-08-08
  • QT?.pro文件使用解析

    QT?.pro文件使用解析

    QT工程的pro文件,在創(chuàng)建工程時(shí)由QTCreater自動(dòng)創(chuàng)建,我們可以往里面添加內(nèi)容,增加庫(kù)文件的聲明,包含路徑、預(yù)處理器定義,生成目錄,輸出中間目錄等等設(shè)置,本文就來(lái)介紹一下
    2022-04-04
  • C語(yǔ)言大廠面試技巧及strcpy()函數(shù)示例詳解

    C語(yǔ)言大廠面試技巧及strcpy()函數(shù)示例詳解

    這篇文章主要為大家介紹了C語(yǔ)言面試技巧,以strcpy()函數(shù)為示例進(jìn)行分析詳解,有需要沖刺大廠的朋友們可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • c語(yǔ)言實(shí)現(xiàn)足球比賽積分統(tǒng)計(jì)系統(tǒng)

    c語(yǔ)言實(shí)現(xiàn)足球比賽積分統(tǒng)計(jì)系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了c語(yǔ)言實(shí)現(xiàn)足球比賽積分統(tǒng)計(jì)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語(yǔ)言:自定義類(lèi)型詳解

    C語(yǔ)言:自定義類(lèi)型詳解

    這篇文章主要介紹了C語(yǔ)言自定義函數(shù)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • QT編寫(xiě)地圖實(shí)現(xiàn)離線輪廓圖的示例代碼

    QT編寫(xiě)地圖實(shí)現(xiàn)離線輪廓圖的示例代碼

    這篇文章主要介紹了在利用QT編寫(xiě)地圖時(shí)常常需要用到的離線輪廓圖,離線輪廓圖使用起來(lái)比線輪廓圖麻煩一點(diǎn),需要自己繪制。感興趣的小伙伴可以學(xué)習(xí)一下
    2021-12-12
  • C++?用紅黑樹(shù)模擬實(shí)現(xiàn)set、map的示例代碼

    C++?用紅黑樹(shù)模擬實(shí)現(xiàn)set、map的示例代碼

    set、map的底層結(jié)構(gòu)是紅黑樹(shù),它們的函數(shù)通過(guò)調(diào)用紅黑樹(shù)的接口來(lái)實(shí)現(xiàn),本文主要介紹了C++?用紅黑樹(shù)模擬實(shí)現(xiàn)set、map,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03

最新評(píng)論

天台县| 攀枝花市| 汾阳市| 介休市| 聂荣县| 建阳市| 揭东县| 措勤县| 环江| 土默特右旗| 固安县| 辽宁省| 临邑县| 会昌县| 祁阳县| 深圳市| 洪江市| 昌图县| 双城市| 唐海县| 尉犁县| 安塞县| 赤水市| 玉林市| 桂林市| 肥东县| 巢湖市| 容城县| 松滋市| 溧阳市| 达日县| 潞西市| 招远市| 时尚| 三江| 丹江口市| 望城县| 沙雅县| 枣庄市| 荔波县| 双城市|