KMP演算法中的next函式的證明

2021-06-18 23:31:07 字數 2311 閱讀 7513

/***摘自《大話資料結構》*/

/*t為字串,

next

為int

陣列,儲存

next值*/

void getnext(string t,int *next)

{int i,j;

i=1;j=0;next[1]=0;

while(i採取分段證明的辦法,證明j往區間(m,k)移動是不正確的,驗證移動到m(next[j]=m)的正確性。

在證明的過程中,都是假設j移動到某個位置之後,討論if判斷條件會成立。因為如果是不成立的話,程式流程又會轉移到j的移動,這樣我們就會陷入死迴圈。而且,這種假設,即if成立,在邏輯上也是成立的,就像遞迴函式一樣,只要一層是正確的,遞迴的肯定也沒問題。

首先觀察這個函式的**,我們可以獲得如下資訊:

(1)      若if成立,則i、j都加1;

(2)      i的值為k,則next[k]已經有了結果,且在下一輪if之前j= next[k];

(3)      當要求next[k]的時候,if中的判斷條件是i=k-1;

證明:前提條件:假設next[k]=s,

即t[1]…[s-1]=t[k-s+1]…[k-1](1)

現求next[k+1]=?根據前面的結論,此時i=k,j=s。令next[s]=m.

現進行if判斷:

(1)   若條件成立,

即t[i]=t[j],也即t[k]=t[s],結合式(1),則有

t[1]…[s-1][s]=t[k-s+1]…[k-1][k]   (2)

則next[k+1]=s+1,即**中的next[i]=j;繼續下一次if判斷。

(2)   若條件不成立,

即t[i] != t[j],則我們需要移動j。

假設向區間 (s , k) 移動,假使使j=s+1,滿足if條件,即t[k]=t[s+1],

根據**,則next[k+1]=s+2,意味著

t[1]…[s-1][s][s+1]=t[k-s]…[k-1][k]   (3)

等式兩邊去掉末位,

t[1]…[s-1][s] =t[k-s]…[k-1]   (4)

從這可以推出next[k]=s+1,與前面矛盾,所以j不能向前移(假若向前移動更多位的話,就會推出next[k]比s+1更大的值)

下面證明j向(m,s)區間移動是不行的。

已知條件:i=k,j=s,next(s)=m,next(k)=s,t[k]!=t[s],需證明移動到m+1是不行的。

現我們假設把j移動到m+1,而不是**中的m。

根據已知條件可以得到:

next(k)=s =>t[1]…[s-1]=t[k-s+1]…[k-1]   (5)

next(s)=m =>t[1]…[m-1]=t[s-m+1]…[s-1]   (6)

if判斷成立,t[k]=t[m+1],則得到next(k+1)=m+2,

t[1]…[m+1]=t[k-m]…[k]   (7)

兩邊去掉右邊一位,則有t[1]…[m] =t[k-m]…[k-1]  (8)

觀察(5),因為s>=m+1,所以k-m>=k-s+1,

所以t[1]…[m] =t[k-m]…[k-1]

= t[s-m]…[s-1]  (由5)

從這裡可以推出,next(s)至少為m+1,與已知矛盾。

顯然,若移動到m+2等就可以得到更大的next(s)的值了。

接下來,我們證明移動j到next[j]的正確性。

設next[j]=m,此時j=s,next[s]=m,移動j到next[s]後,即j=m。

由next[s]=m有:

t[1]…[m-1] =t[s-m+1]…[s-1]   (9)

判斷t[i]==t[j],即t[k]==t[m],條件成立之後,因為s>=m+1,所以

k-m+1>k-s+1,即t[k-m+1]在t[k-s+1]…[k-1][k]中。

取(1)中等式兩邊右邊的m-1項,得到:

t[s-m+1]…[s-1] =t[(k-1)-(m-1)+1]…[k-1]= t[k-m+1]…[k-1]  (10)

又結合(9)(10)有

t[1]…[m-1] =t[k-m+1]…[k-1]   (11)

結合t[k]==t[m],有

t[1]…[m-1][m]=t[k-m+1]…[k-1][k]   (12)

從而next[k+1]=m+1,即**中的next[i]=j。由next的定義可知,j向(0,m)區間移動的話就得不到正確的next值,應為已經找到了j=m滿足要求,j值只能增大,減少就不符合定義。

至此,我們證明了把j回溯到大於m的任何位置都會得到錯誤的結論,且驗證了移動到m可以得到正確的結論。

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 ...

KMP演算法中next函式的解析

今天花了半天的時間,終於把kmp演算法中的next函式整明白了 先看看next資料值的求解方法 位序 1 2 3 4 5 6 7 8 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2next陣列的求解方法是 1.第一位的next值為0 2.第二位的next值為1 後...

KMP演算法中next函式的解析

今天花了半天的時間,終於把kmp演算法中的next函式整明白了 先看看next資料值的求解方法 位序 1 2 3 4 5 6 7 8 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2 next陣列的求解方法是 1.第一位的next值為0 2.第二位的next值為1 ...