字串匹配 學習筆記

2022-05-31 03:48:11 字數 1733 閱讀 9273

kmp

單模式串匹配問題,複雜度$o(n+m)$

思想:充分利用歷史資訊

(鑑於c++字串從0開始標號的緣故,以下陣列下標從0開始)

匹配匹配時,$i$指標指向文字串當前位,$j$指標指向模式串當前位

如果當前位的文字串與模式串匹配成功,即$t_i = p_j$,兩指標同時移動至下一位。

如果當前位文字串與模式串失配,即$t_i \neq p_j$。失配位置之前部分兩串都是相同的。我們不移動文字串。當文字串不動而移動模式串時,實際上就是在前面的相同部分裡,模式串字首與文字串字尾匹配的過程。我們要找到模式串在移動過程中,第乙個在$i$之前與文字串全部匹配的位置(可能是空),這樣才好繼續匹配。這等價於模式串$[0,j)$的最長相同前字尾。

當模式串指標指向$len_p$時,意味著已經找到位置能夠讓模式串與文字串全部匹配。此時應該與處理方法應當與失配一樣,向右移動找到第乙個在$i$之前匹配的位置,也就是$j=nxt_j$。

我們注意到整個演算法的過程中$i$指標是不會往回移動的,這保證了演算法的複雜度。kmp演算法通過處理最長相同前字尾,減少了冗餘匹配次數。注意,字首和字尾是可以有重疊部分的。然而前字尾不能同時是原串自己,這樣就沒有意義了。

在學習kmp匹配的過程中,要時常與暴力$o(nm)$做法作比較,得知kmp的正確性。我們使用$nxt_j$跳過一部分匹配,是因為這部分連在$i$之前的部分都不能匹配,必定不用考慮後面的內容。只有當$i$之前匹配,做下去才是有意義的。

$nxt$的求解過程

定義:$nxt_i$表示區間$[0,i)$中最長相同前字尾的長度。等價於模式串在$i$位置失配時,應該移動至$nxt_i$處。

求解$nxt_i$時,要利用$nxt_$的資訊。

邊界條件:$nxt_0 = -1$

如果$p_}=p_$,利用之前的最長相同前字尾,加上這一位,得到乙個最長相同前字尾。

然而如果不相等呢?退而求其次,繼續往前迭代,直到找到乙個相等的位置為止。

直到找到第一位。這是乙個邊界條件,我們比較第一位和$i-1$。

進行到這一步說明最長相同前字尾的長度為0。

ac自動機

多模式串匹配問題,複雜度$o(n+m \cdot l)$

思想:就是kmp。一句話,失配時在所有模式串的字首裡,尋找當前已匹配部分的最長字尾。

由於模式串可能有前字尾關係,匹配成功後需要一直跳$fail$統計。

有乙個優化,可以在匹配時不需跳$fail$邊(注意是匹配時,不是匹配成功後,成功後如果要優化需要$fail$樹)。就是讓所有不存在的空兒子點成為$fail$的傳送門。這樣的ac自動機成為$trie$圖。

學習筆記 KMP 字串匹配

目錄完整 最初學這個演算法,是在新初一的暑假裡,乙個初三即將畢業的學長給我們講的。當時聽得不是很懂,模板題也就只有 28pts。後來過了好久,又想起來重新學一遍字串,從 kmp 到 sam 都來一遍。於是便有了這片文章。kmp 演算法是由三名姓氏首字母分別為 k m p 的牛人發明的演算法。雖然我不...

KMP字串匹配。。學習。

這個演算法時間複雜度o m n 不回溯例如 a c b c a c b 1 0 0 1 0 1 2 這個是next陣列 當你每次匹配失敗時候。這個匹配串的作用 例如 當時是下標是j,匹配失敗了,就要回到next j 1 1 你失敗那個位置之前一步肯定沒失敗吧 不然就不匹配到這了,然後就回到上一步那個...

字串匹配KMP演算法學習筆記

字串匹配,leetcode28題。時間複雜度o mn 的演算法大家都會,題解裡面官方賬號給出的利用字串雜湊判等的o n 演算法也很優秀。本篇的重點是kmp演算法。如果還不是很好理解,可以看labuladong的題解。乙個kmp演算法易理解版本,講解的部分也很清楚。本篇主要是對此題解做乙個補充,個人感...