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

字符串匹配算法:KMP

這篇具有很好參考價值的文章主要介紹了字符串匹配算法:KMP。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Knuth–Morris–Pratt(KMP)是由三位數(shù)學(xué)家克努斯、莫里斯、普拉特同時發(fā)現(xiàn),所有人們用三個人的名字來稱呼這種算法,KMP是一種改進的字符串匹配算法,它的核心是利用匹配失敗后的信息,盡量減少模式串與主串的匹配次數(shù)以達(dá)到快速匹配的目的。它的時間復(fù)雜度是 O(m+n)

字符匹配:給你兩個字符串 haystack 和 needle ,請你在 haystack 字符串中找出 needle 字符串的第一個匹配項的下標(biāo)(下標(biāo)從 0 開始)。如果 needle 不是 haystack 的一部分,則返回? -1

在介紹KMP算法之前,我們先看一下另一種暴力算法(BF算法)去解字符匹配應(yīng)該怎么做

字符串匹配算法:KMP

?BF算法:時間復(fù)雜度O(m*n)

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        #hi是haystack的當(dāng)前索引
        hi = 0
        haystackLength = len(haystack)
        needleLength = len(needle)
        for i in range(haystackLength - needleLength+1):
            #每次匹配等于和完整的needle的字符串逐一匹配
            if haystack[i:i+needleLength] == needle:
                return i
        return -1

KMP算法:時間復(fù)雜度O(m+n)

KMP構(gòu)造了一個next列表來對應(yīng)改位置索引如果匹配失敗應(yīng)該追溯回到什么位置,這樣我們講減少了匹配次數(shù)

字符串匹配算法:KMP

?那么我們?nèi)绾稳?gòu)造維護我們的next(最長相同前后綴)

構(gòu)造方法為:next[i] 對應(yīng)的下標(biāo),為 P[0...i - 1] 的最長公共前綴后綴的長度,令 next[0] = -1。 具體解釋如下:

例如對于字符串 abcba:
??? 前綴:它的前綴包括:a, ab, abc, abcb,不包括本身;
??? 后綴:它的后綴包括:bcba, cba, ba, a,不包括本身;
??? 最長公共前綴后綴:abcba 的前綴和后綴中只有 a 是公共部分,字符串 a 的長度為 1

我們通過動態(tài)規(guī)劃來維護next,假設(shè)你知道next[0:i-1]位置上所有的回溯值,那么next[i-1]和next[i]相比僅僅多了一個位置,如果這個多的字符可以匹配上,那么next[i]一定等于next[i-1]+1(如下圖所示)

字符串匹配算法:KMP

那么如果匹配不上呢,匹配不上我們回溯到next[i-1]所需要回溯的位置,直到可以匹配上或到達(dá)無法追溯的位置next[0] = -1

    @staticmethod
    def same_start_end_str(p):
        """
        通過needle串來知道每個索引位置對應(yīng)的最長前后綴
        例如ababa的最長前后綴是aba,前后綴是不和needle等長的最長相同前后綴
        """
        next = [-1] * (len(p)+1)
        si = -1
        ei = 0
        pl = len(p)
        while ei < pl :
            if si == -1 or p[si] == p[ei]:
                si += 1
                ei += 1
                next[ei] = si
            else:
                #無法匹配上,繼續(xù)向前追溯
                si = next[si]

        return next

那我們有了next就可以取實現(xiàn)我們KMP算法了,完整代碼如下

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        next = self.same_start_end_str(needle)
        #hi是haystack當(dāng)前索引,ni是needle當(dāng)前索引
        hi = ni = 0
        hl = len(haystack)
        nl = len(needle)
        while hi < hl and ni < nl:
            if ni == -1 or haystack[hi] == needle[ni]:
                hi += 1
                ni += 1
            else:
                ni = next[ni]

        if ni == nl:
            return hi - ni
        else:
            return -1

    @staticmethod
    def same_start_end_str(p):
        """
        通過needle串來知道每個索引位置對應(yīng)的最長前后綴
        例如ababa的最長前后綴是aba,前后綴是不和needle等長的最長相同前后綴
        """
        next = [-1] * (len(p)+1)
        si = -1
        ei = 0
        pl = len(p)
        while ei < pl :
            if si == -1 or p[si] == p[ei]:
                si += 1
                ei += 1
                next[ei] = si
            else:
                #無法匹配上,繼續(xù)向前追溯
                si = next[si]

        return next

?文章來源地址http://www.zghlxwxcb.cn/news/detail-741783.html

到了這里,關(guān)于字符串匹配算法:KMP的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包