日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

KMP算法的动态规划解说

發(fā)布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 KMP算法的动态规划解说 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

理解我接下來所說的東西,需要大家懂得簡單的動態(tài)規(guī)劃。

KMP大家都不陌生了,但是其中計算next數(shù)組總是搞不明白,我想有很多人和我一樣。所以這里用動態(tài)規(guī)劃的思路去描述一下這個問題。

模式串P=c[1]c[2]......c[n]

先設(shè)幾個符號:

suffix(S): S的所有后綴的集合

prefix(S): S的所有前綴的集合

例如:suffix("abcd") = {"","d", "cd", "bcd"}

? ? ? ? ?prefix("abcd") = {"","a", "ab", "abc"}

看到,在這兩個集合都除去了"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呢?其實這個計算過程類似動態(tài)規(guī)劃的轉(zhuǎn)移過程,從初始狀態(tài),不斷的根據(jù)轉(zhuǎn)移方程計算,直至計算出所有的可達狀態(tài)。

那么狀態(tài)怎么定義?初始條件是什么?

設(shè)兩個游標(biāo)p1,p2, p1,p2構(gòu)成的位置對為狀態(tài)<p1,p2>,例如p1在i位置,p2在j位置,i<j,那么狀態(tài)<i, j>就代表c[1]c[2]......c[i]=c[j-i+1]c[j-i+2]......c[j],即串的前i個字符與后i個字符相同。之后我們根據(jù)<i,j>推出<i',j+1>。我們依次計算<i1, 1>,<i2,2>,......,<in,n>。設(shè)LMAX(<i, j>)=i,通過上面對next的定義,我們可知next[j]=MAX{LMAX(<i,j>)|0<=i<j}。

初始化的條件為 next[1] = LMAX(<0, 1>) = 0。假設(shè)我們當(dāng)前所在的狀態(tài)為<i, j>,那么如何推出<i',j+1>呢?這必須得看c[i+1]與c[j+1]的關(guān)系,如果c[i+1]=c[j+1],那么我們到達<i+1,j+1>的狀態(tài);如果c[i+1]!=c[j+1],那么我們得根據(jù)所有可能的<i', j>狀態(tài),判斷c[i'+1]=c[j+1]是否成立,如果成立就到達<i'+1,j+1>狀態(tài)。那么,我們?nèi)绾握业竭@些合法的<i',j>狀態(tài)呢?很慶幸,因為next數(shù)組中天然的保存了我們需要的信息。當(dāng)我們到達<i,j>這個狀態(tài)并且發(fā)現(xiàn)c[i+1]!=c[j+1],那么下一個嘗試的狀態(tài)將是<next[i], j>,看看c[next[i]+1]=c[j+1]是否成立。而且我們發(fā)現(xiàn),只要按照i,next[i],next[next[i]]......這樣下去找到第一個能夠符合轉(zhuǎn)移條件的狀態(tài)就OK了,如果沒有一個能夠使之轉(zhuǎn)移的狀態(tài),就說明沒有一個前綴和當(dāng)前的某個后綴是相等的,那么直接跳轉(zhuǎn)到<0, j+1>這個狀態(tài)。

舉個例子吧: 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],這將嘗試狀態(tài)<next[3],j>=<0,j>,使之轉(zhuǎn)移到下面的狀態(tài)$abcababc <1, 6> next[6]=1| | $abcababc <2, 7> next[7]=2| |$abcababc <3, 8> next[8]=3| |

到此,有的同學(xué)又有疑問了,人家KMP定義的next[i]的意義和你的也不一樣呀。對,確實不一樣。

KMP中對next[i]的定義為:設(shè)文本串為T,模式串為P,p[i]!=T[j]時,應(yīng)該用p[?]與T[j]進行比較。

對應(yīng)于上例,得到的next數(shù)組值應(yīng)為

KMP的next: -1 1 1 1 2 3 2 3
我們的next: ?0 0 0 1 2 1 2 3

怎么通過我們的next獲取到正確的next呢?非常簡單,從后往前循環(huán)做next[i] = next[i-1]+1,之后next[1]=-1就哦了。

總結(jié)

以上是生活随笔為你收集整理的KMP算法的动态规划解说的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。