鄧俊輝老師的課上給出了一種普遍的kmp演算法優化,但是沒有給出這種優化的正確性證明。或許這種正確性是顯而易見的,但這裡還是研究了一下這個演算法的正確性問題。
int
*buildnext
(char
* p)
else
//原演算法
j = next[j]
;//優化演算法
j = newnext[j];}
return next;
}
顯然,演算法的優化核心即在於對p[i]
和p[j]
相等時的處理,亦即,若目標串t[k]
與p[i]
不可匹配,則t[k]
必然與p[j]
不可匹配,回溯至j
顯然是一種遠遠不夠的回溯,按照原演算法的執行邏輯,則會遞迴j = next[j]
直至t[k] = p[i] != p[j]
。很自然的,我們可以通過遞推改進這個遞迴公式,這個的正確性是顯然的,通過保證前面滿足條件來保證後面均滿足條件。
優化演算法的實際變動不僅於此,由於改變的next
陣列的含義,那麼顯然,我們需要保證j = newnext[j]
仍能發揮原先的作用,才可保證j
的取值滿足newnext
陣列的正確性。顯然,在這個演算法中,newnext
陣列表示的是在p[0, j)中,p[0, t) = p[j-t, j) && p[t] != p[j] 情況下t的最大值
。因此,若p[i] != p[j]
,則可令k = j
,遞迴k = next[k]
直至p[j] != p[k]
,此時p[i]
與p[j]
方有相同的可能。此回溯與newnext
陣列的含義不謀而合,因此我們可以使用j = newnext[j]
來代替原演算法的j = next[j]
,演算法的功能仍得以儲存。
因此,整個優化演算法過程中,j
的變化仍與原演算法相同,僅有些微小的變化,而這些微小的變化僅僅是「跳步」迭代而已,這保證了next
陣列與newnext
陣列在p[i] != p[j]
情況下取值相同,演算法的正確性得以保證。
Dijkstra演算法正確性證明
問題 求圖中點1到其他各點的最短距離 演算法描述 設初始時圖的所有點的集合u 把起點s放入初始集合set中 u u set set 找s經過集合set中的點,能達到的距離最短的點k k in u 將k併入set 言外之意k的前乙個點必然屬於set u u set set 由於每次引入的只有乙個點k,...
Dijkstra演算法正確性證明
問題 求圖中點1到其他各點的最短距離 策略 1.把起點1放入初始集合set中,從剩餘的點中,選取到set 此時set中只有1個點 距離最近的點,併入集合set中,2.從剩餘的點中,找經過集合set,到起點1的最短距離,將最短邊併入set集合 3.依次迴圈,直到所有的邊都併入set 變數的命名 set...
貪心演算法正確性證明
貪心演算法正確性證明 wiki定義 貪心演算法 英語 greedy algorithm 又稱貪婪演算法,是一種在每一步選擇中都採取在當前狀態下最好或最優 即最有利 的選擇,從而希望導致結果是最好或最優的演算法。比如在旅行推銷員問題中,如果旅行員每次都選擇最近的城市,那這就是一種貪心演算法。用大白話說...