国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

這篇具有很好參考價(jià)值的文章主要介紹了【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

?前言:

?KMP算法簡(jiǎn)介:

引入概念:

前綴后綴

前綴表:

簡(jiǎn)單例子:

暴力遍歷:

KMP算法:?

?KMP算法難點(diǎn):

總結(jié):


?前言:

本篇我們將詳細(xì)的從理論層面介紹一下什么是KMP算法,相對(duì)應(yīng)的力扣刷題專欄里也會(huì)有相對(duì)應(yīng)的習(xí)題,歡迎各位前往閱讀。

?KMP算法簡(jiǎn)介:

? ? ? ? ?KMP算法是一種字符串匹配算法,用于在一個(gè)文本串中查找某個(gè)子串出現(xiàn)的位置。KMP算法的原理是根據(jù)模式串的特點(diǎn),在匹配過程中避免重復(fù)匹配已經(jīng)匹配過的部分。具體來說,KMP算法維護(hù)兩個(gè)指針:i和j,表示當(dāng)前匹配位置和模式串匹配的起點(diǎn)。當(dāng)出現(xiàn)不匹配時(shí),通過已匹配部分構(gòu)建一個(gè)next數(shù)組,用以確定模式串下一次匹配起點(diǎn)的位置。

? ? ? ? KMP算法的時(shí)間復(fù)雜度為O(n+m),其中n為文本串長(zhǎng)度,m為模式串長(zhǎng)度。KMP算法應(yīng)用廣泛,例如在文件查找、模糊查詢等領(lǐng)域都有廣泛的應(yīng)用。

KMP算法的本質(zhì)就是跳過一部分暴力循環(huán)下的無效比較,達(dá)到節(jié)省時(shí)間復(fù)雜度的目的

引入概念:

前綴后綴

前綴:字符串中包含首字母但是不包含尾字符的所有子串

后綴:字符串中包含尾字母但是不包含首字符的所有子串

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

舉例:

字符串aabaaf的前綴后綴分別有:

前綴 后綴
a a

aa

aa
aab baa
aaba abaa
aabaa abaaf

前綴表:

一個(gè)字符串中每一個(gè)子串都有自己的前綴和后綴,也就都有自己的最長(zhǎng)相等前后綴長(zhǎng)度,這些長(zhǎng)度組成的一個(gè)數(shù)組,我們把它叫做前綴表

舉例:
字符串aabaaf的前綴表:

子串 前綴 后綴 最長(zhǎng)相等前后綴長(zhǎng)度
a 0
aa a a 1
aab a,aa b,ab 0
aaba a,aa,aab a,ba,aba 1
aabaa a,aa,aab,aaba a,aa,baa,abaa 2
aabaaf a,aa,aab,aaba,aabaa f,af,aaf,baaf,abaaf 0

簡(jiǎn)單例子:

假設(shè)我們要在父串aabaabaaf中尋找子串aabaaf

暴力遍歷:

正常情況是我們?cè)诟复兄鹨槐闅v,父串與子串挨個(gè)匹配,直到找到與子串完全一致的為止:
?【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

錯(cuò)誤之后重新比較:
?【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

?最終:

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

我們可以發(fā)現(xiàn)暴力遍歷之所以時(shí)間復(fù)雜度高,是因?yàn)橹灰鲥e(cuò),父指針與子指針就會(huì)不斷的回溯。第一次出錯(cuò)后,父類指針回溯到1,子類指針回溯到0,重新開始比較,第二次出錯(cuò)父類指針回溯到2,子類指針回溯到0,重新開始比較。如此類推。大量的回溯帶來了高昂的時(shí)間成本,我們就在想如何才能夠精簡(jiǎn)回溯,于是經(jīng)過不懈努力,我們創(chuàng)造出了KPM算法。

? ?KMP算法:
【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

KMP算法采取了自定義i和j的回溯,通過控制i和j的回溯位置來降低回溯的時(shí)間成本。

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

?此時(shí)按照暴力遍歷的思路,我們是讓i等于1,j等于0重新開始第二輪遍歷,但是我們KMP算法給出了新的思路:

我們不對(duì)已經(jīng)比較過的字符串進(jìn)行二次比較,就節(jié)省了回溯成本,既然綠色前綴和紅色后綴相等,都是aa,那么下一次我們讓子類的綠色前綴對(duì)齊父類的紅色后綴,這樣我們就不用回溯i和j,也可以開啟新一輪的字符串對(duì)比

為什么可以這樣操作呢?

前提是我們已經(jīng)知道前面字符串只有b和f不匹配,其他的一切都是匹配的,那么此時(shí)往前回溯字符串

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

?找到兩串最長(zhǎng)的相等的一個(gè)包含首字母的字符串(前綴),一個(gè)包含尾字母的字符串(后綴),因?yàn)槎呤窍嗟鹊模敲次覀兙涂梢缘玫紸BCD四個(gè)子串:

那其實(shí)我們這里不移動(dòng)最長(zhǎng)的也可以,只不過移動(dòng)最長(zhǎng)的會(huì)簡(jiǎn)化的更多而已。

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

那么既然B和D匹配,D又和C匹配,也就是我們?cè)谙乱淮窝h(huán)的時(shí)候,可以直接讓B對(duì)齊C,而BC又是匹配的,我們不用重新對(duì)其進(jìn)行匹配,可以直接從此處的i和j開始。

【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法?而不斷的循環(huán)這種比較方法,直至找到父類中符合要求的子串,就實(shí)現(xiàn)了KMP算法下的字符串匹配。

?

通過這個(gè)我們可以總結(jié)出來模板:

? ? ? ? 每一次我們都找到不匹配字母前面的字符串(例如我們這里aabaaff不匹配,前置字符串就是aabaa)然后找出他的最長(zhǎng)相等前綴后綴長(zhǎng)度(找出有無符合上述這種紅綠組合的),這里的最長(zhǎng)相等前綴后綴是2,最后我們讓i不回溯,j回退到最長(zhǎng)相等前綴后綴位置開始向后匹配。

? ? 而next數(shù)組其實(shí)就是我們?yōu)榱朔奖闶褂貌黄ヅ渥帜盖爸玫淖址淖铋L(zhǎng)相等前綴后綴長(zhǎng)度,我們自己進(jìn)行提前算出這個(gè)字符串的所有子串的最長(zhǎng)相等前綴后綴長(zhǎng)度,存儲(chǔ)在一個(gè)數(shù)組里面方便直接使用,我們給這個(gè)把這個(gè)數(shù)組叫做next數(shù)組

? ? ?需要注意的是next數(shù)組的版本多種多樣,通常會(huì)對(duì)里面的數(shù)據(jù)進(jìn)行各種處理。不過本質(zhì)存放的都是前綴表,因此我們其實(shí)可以不對(duì)next數(shù)組做任何處理,就讓他存放前綴表,依然可以實(shí)現(xiàn)KMP算法。

以下這句話,對(duì)于理解為什么使用前綴表可以告訴我們匹配失敗之后跳到哪里重新匹配 非常重要!

下標(biāo)5之前這部分的字符串(也就是字符串a(chǎn)abaa)的最長(zhǎng)相等的前綴 和 后綴字符串是 子字符串a(chǎn)a ,因?yàn)檎业搅俗铋L(zhǎng)相等的前綴和后綴,匹配失敗的位置是后綴子串的后面,那么我們找到與其相同的前綴的后面從新匹配就可以了。

所以前綴表具有告訴我們當(dāng)前位置匹配失敗,跳到之前已經(jīng)匹配過的地方的能力。

next表的種類:

我們還是以aabaaf舉例:
【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法

?KMP算法難點(diǎn):

整個(gè)KMP算法都可以看作兩部分

  • 內(nèi)核:前綴表的求解,建立next數(shù)組
  • 外殼:利用前綴表控制子字符串的回溯

主要的難點(diǎn)在于:如何求字符串的前綴表?

其實(shí)字符串的前綴表數(shù)組計(jì)算本質(zhì)上也是在運(yùn)用KMP算法。

它是把字符串的前綴當(dāng)作了模式串,把字符的后綴當(dāng)成了文本串

void getNext(int* next, const string& s) {
        int j = 0;
        next[0] = 0;
        for(int i = 1; i < s.size(); i++) {
            while (j > 0 && s[i] != s[j]) { // j要保證大于0,因?yàn)橄旅嬗腥-1作為數(shù)組下標(biāo)的操作
                j = next[j - 1]; // 注意這里,是要找前一位的對(duì)應(yīng)的回退位置了
            }
            if (s[i] == s[j]) {
                j++;
            }
            next[i] = j;
        }
    }

KMP算法完整版:

class Solution {
public:
    void getNext(int* next, const string& s) {
        int j = 0;
        next[0] = 0;
        for(int i = 1; i < s.size(); i++) {
            while (j > 0 && s[i] != s[j]) {
                j = next[j - 1];
            }
            if (s[i] == s[j]) {
                j++;
            }
            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) {
        if (needle.size() == 0) {
            return 0;
        }
        int next[needle.size()];
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) {
            while(j > 0 && haystack[i] != needle[j]) {
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == needle.size() ) {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }
};

總結(jié):

KMP算法的優(yōu)點(diǎn)主要包括以下幾點(diǎn):

1. 高效率:KMP算法的時(shí)間復(fù)雜度為O(n+m),其中n是文本串長(zhǎng)度,m是模式串長(zhǎng)度,相比暴力匹配算法的時(shí)間復(fù)雜度O(nm)有很大的提升。

2. 可擴(kuò)展性:KMP算法不要求文本和模式串的長(zhǎng)度一致,因此能夠有效地處理不同長(zhǎng)度的字符串匹配問題。此外,KMP算法還可以支持多模式匹配,即在一個(gè)文本串中查找多個(gè)模式串。

3. 避免重復(fù)匹配:KMP算法通過計(jì)算模式串的next數(shù)組來避免重復(fù)匹配已經(jīng)匹配過的部分,從而提高了匹配效率。

4. 空間復(fù)雜度低:KMP算法只需要一個(gè)長(zhǎng)度為m的next數(shù)組來存儲(chǔ)模式串中最長(zhǎng)相同前后綴的長(zhǎng)度,空間復(fù)雜度相對(duì)較低。

5. 實(shí)現(xiàn)簡(jiǎn)單:KMP算法的實(shí)現(xiàn)相對(duì)簡(jiǎn)單,易于理解和使用。

總之,KMP算法是一種高效、可擴(kuò)展、避免重復(fù)匹配、空間復(fù)雜度低、實(shí)現(xiàn)簡(jiǎn)單的字符串匹配算法,對(duì)于字符串匹配問題具有廣泛的應(yīng)用價(jià)值。

今天的內(nèi)容到這里就結(jié)束了,感謝大家的閱讀。

如果我的內(nèi)容對(duì)你有幫助,請(qǐng)點(diǎn)贊,評(píng)論,收藏。創(chuàng)作不易,大家的支持就是我堅(jiān)持下去的動(dòng)力!

?【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法文章來源地址http://www.zghlxwxcb.cn/news/detail-479713.html

到了這里,關(guān)于【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第一篇】KMP算法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第十篇】動(dòng)態(tài)規(guī)劃

    【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第十篇】動(dòng)態(tài)規(guī)劃

    目錄 前言: 動(dòng)態(tài)規(guī)劃: 常見應(yīng)用: 解題步驟: ?動(dòng)態(tài)規(guī)劃的簡(jiǎn)化步驟: 案例: 509. 斐波那契數(shù) - 力扣(LeetCode) 70. 爬樓梯 - 力扣(LeetCode) 62. 不同路徑 - 力扣(LeetCode) 總結(jié): ? ? ? ? 本文我們將為大家講解一下動(dòng)態(tài)規(guī)劃的理論知識(shí),并且會(huì)講解幾道力扣的經(jīng)典例題。

    2024年02月11日
    瀏覽(30)
  • 【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第九篇】棧與隊(duì)列

    【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第九篇】棧與隊(duì)列

    目錄 ?前言: 棧: 棧的實(shí)際應(yīng)用:? 隊(duì)列: 隊(duì)列的實(shí)際應(yīng)用: 總結(jié): ? ? ? ? 棧與隊(duì)列是我們學(xué)習(xí)的兩個(gè)經(jīng)典的數(shù)據(jù)結(jié)構(gòu),這兩個(gè)數(shù)據(jù)結(jié)構(gòu)應(yīng)用廣泛,在計(jì)算機(jī)內(nèi)有很多底層應(yīng)用,而很多算法也是依靠棧和隊(duì)列來實(shí)現(xiàn)的,因此我們要想學(xué)好數(shù)據(jù)結(jié)構(gòu)與算法,就要學(xué)好棧與

    2024年02月15日
    瀏覽(13)
  • 【夜深人靜學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法 | 第十二篇】動(dòng)態(tài)規(guī)劃——背包問題

    【夜深人靜學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法 | 第十二篇】動(dòng)態(tài)規(guī)劃——背包問題

    ? 目錄 ?前言: ?01背包問題: 二維數(shù)組思路: 一維數(shù)組思路: 總結(jié): ? ? ? 在前面我們學(xué)習(xí)動(dòng)態(tài)規(guī)劃理論知識(shí)的時(shí)候,我就講過要介紹一下背包問題,那么今天我們就來講解一下背包問題。 在這里我們只介紹 01背包 ,至于分組背包和混合背包這種的已經(jīng)屬于競(jìng)賽級(jí)別的

    2024年02月12日
    瀏覽(19)
  • 【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第二篇】后綴(逆波蘭)表達(dá)式

    【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第二篇】后綴(逆波蘭)表達(dá)式

    目錄 前言:? 中綴表達(dá)式: ?后綴表達(dá)式: 中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式: 后綴表達(dá)式計(jì)算結(jié)果: 總結(jié):? 計(jì)算機(jī)在計(jì)算四則運(yùn)算的時(shí)候,由于括號(hào)以及運(yùn)算優(yōu)先級(jí)的存在,并不能夠很好的處理所有的運(yùn)算,為了處理這種情況,我們引入了后綴表達(dá)式來優(yōu)化算法。 ????? ??

    2024年02月13日
    瀏覽(33)
  • 【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第四篇】手撕二叉樹遍歷

    【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第四篇】手撕二叉樹遍歷

    目錄 前言: 二叉樹遍歷方式: 手撕前中后序遍歷(遞歸)的三大準(zhǔn)備 深度優(yōu)先搜索:? 手撕前中后遍歷(遞歸): 手撕前中后序遍歷(迭代): 深度優(yōu)先搜索: 總結(jié): ? ? ? ? 今天我們將帶領(lǐng)大家手撕二叉樹的遍歷,本篇會(huì)分別講解深度優(yōu)先搜索法和廣度優(yōu)先有搜索法下

    2024年02月09日
    瀏覽(24)
  • 【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第七篇】時(shí)間復(fù)雜度與空間復(fù)雜度

    【夜深人靜學(xué)數(shù)據(jù)結(jié)構(gòu)與算法 | 第七篇】時(shí)間復(fù)雜度與空間復(fù)雜度

    前言:? 引入:? 時(shí)間復(fù)雜度: ?案例: 空間復(fù)雜度: 案例: TIPS:? ? ? ? 總結(jié): ????????今天我們將來介紹時(shí)間復(fù)雜度和空間復(fù)雜度,我們代碼的優(yōu)劣就是依靠這個(gè)在評(píng)判,以此為背景,我們誕生出了不少的經(jīng)典思路:用時(shí)間換空間,用空間換取時(shí)間。而大多數(shù)同學(xué)

    2024年02月10日
    瀏覽(23)
  • 夜深人靜學(xué)32系列10——GPIO中斷/NVIC/EXTI/SYSCFG詳解,外部中斷控制LED

    夜深人靜學(xué)32系列10——GPIO中斷/NVIC/EXTI/SYSCFG詳解,外部中斷控制LED

    上期我們學(xué)習(xí)了GPIO驅(qū)動(dòng)數(shù)碼管/蜂鳴器/LED和按鍵等外設(shè),本期我們一起來學(xué)習(xí)STM32中斷的相關(guān)內(nèi)容 當(dāng)CPU正在處理某個(gè)事件的時(shí)候,外界發(fā)生了緊急事件請(qǐng)求,CPU需要暫停當(dāng)前的工作,轉(zhuǎn)而去處理這個(gè)緊急事件,處理完之后,再次回到之前被中斷的地方,繼續(xù)執(zhí)行原來的工作,

    2024年01月16日
    瀏覽(20)
  • 算法競(jìng)賽:初級(jí)算法(第一章:基礎(chǔ)數(shù)據(jù)結(jié)構(gòu))

    動(dòng)態(tài)鏈表 動(dòng)態(tài)鏈表需要 臨時(shí)分配鏈表節(jié)點(diǎn) ,使用完畢后釋放。 優(yōu)點(diǎn) :能及時(shí)釋放空間,不使用多余內(nèi)存 缺點(diǎn) :需要管理空間,容易出錯(cuò)(競(jìng)賽一般不用動(dòng)態(tài)鏈表) 靜態(tài)鏈表 靜態(tài)鏈表使用 預(yù)先分配的一段連續(xù)空間 存儲(chǔ)鏈表,這種鏈表在邏輯上是成立的。 有兩種做法:

    2024年01月19日
    瀏覽(32)
  • 數(shù)據(jù)結(jié)構(gòu)英文習(xí)題解析-第一章 算法復(fù)雜度分析Algorithm Analysis

    前言:最近快到FDS考試了,po重刷了一下學(xué)校的題目,自己整理了一些解析orz 因?yàn)閜o在自己找解析和學(xué)習(xí)的過程中非常痛苦,所以在此共享一下我的題目和自己寫的解題思路,歡迎各位指出錯(cuò)誤~全章節(jié)預(yù)計(jì)會(huì)陸續(xù)更新,可在專欄查看~ HW1 1. The major task of algorithm analysis is to an

    2024年03月12日
    瀏覽(87)
  • 第一百零五天學(xué)習(xí)記錄:數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ):順序表(王卓教學(xué)視頻)

    第一百零五天學(xué)習(xí)記錄:數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ):順序表(王卓教學(xué)視頻)

    注:筆記截圖均來自王卓數(shù)據(jù)結(jié)構(gòu)教學(xué)視頻 線性表是具有相同特性的數(shù)據(jù)元素的一個(gè)有限序列 同一線性表中的元素必定具有相同特性,數(shù)據(jù)元素間的關(guān)系是線性關(guān)系。 稀疏多項(xiàng)式的運(yùn)算 順序存儲(chǔ)結(jié)構(gòu)存在的問題 1、存儲(chǔ)空間分配不靈活 2、運(yùn)算的空間復(fù)雜度高 引出鏈?zhǔn)酱鎯?chǔ)

    2024年02月15日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包