理解我接下來所說的東西,需要大家懂得簡單的動態規劃。
kmp大家都不陌生了,但是其中計算next陣列總是搞不明白,我想有很多人和我一樣。所以這裡用動態規劃的思路去描述一下這個問題。
模式串p=c[1]c[2]......c[n]
先設幾個符號:
suffix(s): s的所有字尾的集合
prefix(s): s的所有字首的集合
例如:suffix("abcd") =
prefix("abcd") =
看到,在這兩個集合都除去了"abcd"本身。
真對p定義next的意義:next[i]代表的意義是suffix(c[1]c[2]......c[i])與prefix(c[1]c[2]......c[i])兩個集合中最長相同串的長度(不包括串c[1]c[2]......c[i])。那麼如何計算next呢?其實這個計算過程類似動態規劃的轉移過程,從初始狀態,不斷的根據轉移方程計算,直至計算出所有的可達狀態。
那麼狀態怎麼定義?初始條件是什麼?
設兩個游標p1,p2, p1,p2構成的位置對為狀態,例如p1在i位置,p2在j位置,i就代表c[1]c[2]......c[i]=c[j-i+1]c[j-i+2]......c[j],即串的前i個字元與後i個字元相同。之後我們根據推出。我們依次計算,,......,。設lmax()=i,通過上面對next的定義,我們可知next[j]=max{lmax()|0<=i初始化的條件為 next[1] = lmax(<0, 1>) = 0。假設我們當前所在的狀態為,那麼如何推出呢?這必須得看c[i+1]與c[j+1]的關係,如果c[i+1]=c[j+1],那麼我們到達的狀態;如果c[i+1]!=c[j+1],那麼我們得根據所有可能的狀態,判斷c[i'+1]=c[j+1]是否成立,如果成立就到達狀態。那麼,我們如何找到這些合法的狀態呢?很慶幸,因為next陣列中天然的儲存了我們需要的資訊。當我們到達這個狀態並且發現c[i+1]!=c[j+1],那麼下乙個嘗試的狀態將是,看看c[next[i]+1]=c[j+1]是否成立。而且我們發現,只要按照i,next[i],next[next[i]]......這樣下去找到第乙個能夠符合轉移條件的狀態就ok了,如果沒有乙個能夠使之轉移的狀態,就說明沒有乙個字首和當前的某個字尾是相等的,那麼直接跳轉到<0, j+1>這個狀態。
舉個例子吧: s=abcababc為了方便理解,在s前加乙個萬用字元$
$abcababc
<0, 1> next[1]=0
||$abcababc
<0, 2> next[2]=0
| |$abcababc
<0, 3> next[3]=0
| |$abcababc
<1, 4> next[4]=1
| |$abcababc
<2, 5> next[5]=2
| |下一步s[
3]!=s[6],這將嘗試狀態3],j>=<0,j>,使之轉移到下面的狀態
$abcababc
<1, 6> next[6]=1
| |$abcababc
<2, 7> next[7]=2
| |$abcababc
<3, 8> next[8]=3
| |
到此,有的同學又有疑問了,人家kmp定義的next[i]的意義和你的也不一樣呀。對,確實不一樣。
kmp中對next[i]的定義為:設文字串為t,模式串為p,p[i]!=t[j]時,應該用p[?]與t[j]進行比較。
對應於上例,得到的next陣列值應為
kmp的next: -1 1 1 1 2 3 2 3
我們的next: 0 0 0 1 2 1 2 3
怎麼通過我們的next獲取到正確的next呢?非常簡單,從後往前迴圈做next[i] = next[i-1]+1,之後next[1]=-1就哦了。
KMP演算法的動態規劃解說
理解我接下來所說的東西,需要大家懂得簡單的動態規劃。kmp大家都不陌生了,但是其中計算next陣列總是搞不明白,我想有很多人和我一樣。所以這裡用動態規劃的思路去描述一下這個問題。模式串p c 1 c 2 c n 先設幾個符號 suffix s s的所有字尾的集合 prefix s s的所有字首的集合...
KMP 動態規劃演算法
kmp 演算法詳解 知乎 zhihu.com 這個使它演算法的鏈結 細節的部分大佬已經說過了,我就說一下簡略的步驟和相應的方法把,如果科班出身的應該看的懂 這個演算法的核心是乙個確定有限自動機,可以這麼說,如果你的確定有限自動機寫出來了,那麼這個演算法已經完成百分之80了。寫出乙個二維陣列,這個二維...
演算法 動態規劃
動態規劃 把多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解 演算法例子 1.鋼條切割 serling 公司購買長鋼條,將其切割為短鋼條,切割工序假設沒有成本支出,公司管理層希望確定最佳的切割方案。假設serling公司 一段長度為i英吋的鋼條的 為pi。鋼條的長度為整英吋,下表給出...