KMP算法的正確性證明及一個小優化


直接把作業帖上來是不是有點不太公道呀。。。

無所謂啦反正各位看着開心就行

KMP算法

對於模式串$P$,建立其前綴函數$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置為結束的可以匹配到前綴的最長后綴的長度(也可以理解為那個前綴的結束位置),在匹配中,若$P[i]$與$S[j]$失配,則令$i=N [i-1] +1$ ,否則$i=i+1,j=j+1$

現考慮如何構造$N$ ,設當前以計算出$N[1..i-1]$ ,則令$k=N[i-1]$ ,若 $P[k+1]=P[i]$,則令$N[i]=k+1$ ,否則令$k=N[k]$ 。重復上述過程,直至找到$N[i]$

可證該算法能在$\Theta(|P|) $ 的時間內構造出前綴函數$N$ ,在$\Theta (|S|)$ 的時間內完成匹配,總的時間復雜度為$\Theta(|S|+|P|)$

KMP算法的正確性證明

先證明匹配過程的正確性:

在過程中,若$P[1..q]$ 與$S[s+1...s+q]$ 匹配,而$P[q+1]$與$S[s+q+1]$ 失配,那么由$N$的定義可立即得出$P[1..N[q]]$ 與 $S[s+q-N[q]+1...s+q]$ 匹配,而$S[1...t]$與$S[s+q-t+1...s+q]$ 失配$(N[q]<t<q)$ ,即只需檢驗$P[N[q]+1]$ 與$S[s+q+1]$ 的匹配情況即可,匹配過程的正確性即可得證。

接下來證明前綴函數$N$計算的正確性:

令$N^*[q]= \{N[q],N^{(2)}[q],…,N^{(t)}[q]\}$ 其中$N^{(t)}[q]=N^{(t-1)}[q],N^{(0)}[q]=N[q]$ ,那么$N^*[q]$ 為以q位置為結束的可以匹配到前綴的后綴的所有長度(即匹配到所有前綴的位置),同時有$N[q]-1\in N^*[q-1]$ ,因此只需從大到小枚舉$N^*[q-1]$ 中的元素並通過判斷即可得出$N[q]$ 。
KMP算法的時間復雜度證明

在匹配時:$i,j$增長了$|S|$ ,而在$i=N[i-1]+1$ 中,$i$ 至少減少1,即該語句至多執行了$|S|$次,因此時間復雜度為$\Theta(|S|)$。

構造前綴函數$N$ 時: 我們考慮k的變化,我們可以得到,在每次$k=N[k]$ 中,$k$ 至少減少1,又因為$k$隨$i$增加了$|P|$次,即該語句至多執行$|P|$ 次,因此時間復雜度為$\Theta(|P|)$ 。

因此總的時間復雜度為$\Theta(|S|+|P|)$ 。
KMP算法的優化

我們希望通過優化,為了減少失配的概率,因此提出如下改進:

在構造$N'$數組時,當$P[k+1]=P[i]$ 時,若$P[i+1]=P[k+2]$ 則$N'[i]=k+1$ 否則$N'[i]=N'[k+1]$ 。
該優化的正確性證明

在匹配時,我們發現,若$P[q+1]$ 與$S[s+q+1]$失配,同時$P[q+1]=P[N^{(t)}[q]+1]$ ,則$P[N^{(t)}[q]+1]$一定與$S[s+q+1]$ 失配,因此若$P[N[q]+1]=P[q+1]$ ,則該比較一定失配,無需考慮。

在該優化中,由該函數的遞歸求法可得,$N'[q]=max\{N^*[q]且P[q+1]\neq P[N^{(t)}[q]+1]\}$ ,因此$N'[q]$ 依舊能枚舉完所有可能匹配的前綴,同時減少失配概率。
該優化對算法空間與時間復雜度的影響

由於該優化只是改變了N數組的構造方法,因此對空間復雜度無影響。

時間復雜度的證明同KMP的證明,可得對最壞情況下的時間復雜度無影響

由於該算法避免了出現$P[N[q]+1]=P[q+1]$的情況,因此對於有較多重復子串的模式串有較好的優化效果(如aaaab,abcabcabcd)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM