kmp是上學期學資料結構時候學的,當時就沒學太明白,後來又自己琢磨了幾次,但始終是一知半解。今天起床了又想起來kmp,以下是思考得到的一點東西。
首先學過kmp的都知道要寫兩個函式,乙個計算next陣列,乙個kmp主體函式,那麼next陣列裡存的到底是啥呢。首先答案是:next[i]存的是字串[0,i]的前字尾最長公共長度減1的值。下面先解釋下前字尾。
引用張別人的圖:
也就是說只有乙個元素時候前字尾都為空,即不能拿整個字串作為字首or字尾,注意這點即可。
我們把第i位對應的最大公共前字尾長度減1的值作為next[i]的值,這一點是為了之後計算的方便,後續會提到。
下面是next陣列的計算函式
//建立next陣列
int create_next(int* address,int len,string str)
if(str[k+1]==str[i])
address[i]=k;
}}
首先address[0]=-1,原因上面說了。每次for迴圈裡的i是代表字串的游標,每次for迴圈幹的事是計算出字串[0,i]的最長公共前字尾元素個數,當然我們可以乙個個數,先看str[0]=str[i]成立不成立,再看str[0]=str[i-1]&&str[1]=str[i]成立不成立,依次類推。但是這樣重複考察了太多元素,故我們採用簡便一點的方法,我畫了個圖。
如圖,前後黑括號代表[0,i-1]的最長公共前字尾,但str[k+1]!=str[i],那麼我們要找黑括號裡的更小的藍括號,讓前後藍括號相同。注意看圖,找到滿足上面條件藍括號的時候,左邊藍括號就在左邊黑括號的左端,右邊藍括號在右邊黑括號的右端,這不就是求[0,k]或者[i-1-k,i-1]的最長公共前字尾長度麼?再看下k=next[k],是不是這回懂為啥這麼寫了。從最開始的黑括號尋找藍括號的部分就是next函式第一部分,也就是下面這個while迴圈做的事情,想一想是不是
int k=address[i-1];
while(str[k+1]!=str[i]&&k>-1)
找到上面的一對藍括號之後,就出去while迴圈了,接下來是:
if(str[k+1]==str[i])
address[i]=k;
閒著沒事又敲了個python的:
def create_next(next_list,str):
str_len=len(str)
next_list.clear()
k=-1
for i in range(str_len):
while k!=-1 and str[k+1]!=str[i]:
k=next_list[k]
if str[k+1]==str[i]: #若k為-1也成立
k+=1
next_list=
def kmp(target,pattern):
#target目標串,pattern模式串
create_next(next_list,pattern)
tar_len=len(target)
pat_len=len(pattern)
k=-1
for i in range(tar_len):
while k!=-1 and target[i]!=pattern[k+1]:
k=next_list[k]
if target[i]==pattern[k+1]:
k+=1
if k==pat_len-1: #模式串全部匹配,即匹配成功
return i-pat_len+1
x="bacbababadababacmbabacaddababacasdsd"
y="ababaca"
print(kmp(x,y))
關於KMP的next陣列
明明寫的和課本一樣,但是在pta就是不正確,參考了別人的答案,發現有乙個地方不一樣記錄一下!include include include int next1 1000 next1 j k,表示當t i p j 時,j指標的下乙個位置。求字串在主串中第一次出現的位置 void get next1 c...
關於KMP演算法的next陣列
kmp的next陣列求法是很不容易搞清楚的一部分,也是最重要的一部分。我這篇文章就以我自己的感悟來慢慢推導一下吧!保證你看完過後是知其然,也知其所以然。如果你還不知道kmp是什麼,請先閱讀上面的鏈結,先搞懂kmp是要幹什麼。下面我們就來說說kmp的next陣列求法。kmp的next陣列簡單來說,假設...
KMP演算法中的next函式
kmp演算法詳解看 next i 表示當模式串t i 與主串失配時,模式串的索引回溯到next i 主串的索引不變 下面串的下標均從0開始 1 i 0 next i max k 0 k 證明模式串next函式的可行性 當t i 與 s j 失配時,即 t i s j 時 可得t 0.i 1 s j ...