算法:字符串匹配算法:KMP算法

字符串匹配算法
暴力算法BF算法,利用哈希值進行比較的RK算法,以及儘量減少比較次數的BM算法
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

next 數組

next數組到底是個什麼鬼呢?這是一個一維整型數組,數組的下標代表了“已匹配前綴的下一個位置”,元素的值則是“最長可匹配前綴子串的下一個位置”。

或許這樣的描述有些晦澀,我們來看一下圖:
在這裏插入圖片描述
當模式串的第一個字符就和主串不匹配時,並不存在已匹配前綴子串,更不存在最長可匹配前綴子串。這種情況對應的next數組下標是0,next[0]的元素值也是0。

如果已匹配前綴是G、GT、GTGTGC,並不存在最長可匹配前綴子串,所以對應的next數組元素值(next[1],next[2],next[6])同樣是0。

GTG的最長可匹配前綴是G,對應數組中的next[3],元素值是1。

以此類推,
GTGT 對應 next[4],元素值是2。
GTGTG 對應 next[5],元素值是3。

有了next數組,我們就可以通過已匹配前綴的下一個位置(壞字符位置),快速尋找到最長可匹配前綴的下一個位置,然後把這兩個位置對齊。

比如下面的場景,我們通過壞字符下標5,可以找到next[5]=3,即最長可匹配前綴的下一個位置:
在這裏插入圖片描述
說完了next數組是什麼,接下來我們再來思考一下,如何事先生成這個next數組呢?

由於已匹配前綴數組在主串和模式串當中是相同的,所以我們僅僅依據模式串,就足以生成next數組。

最簡單的方法是從最長的前綴子串開始,把每一種可能情況都做一次比較。

假設模式串的長度是m,生成next數組所需的最大總比較次數是1+2+3+4+…+m-2 次。

顯然,這種方法的效率非常低,如何進行優化呢?

我們可以採用類似“動態規劃”的方法。首先next[0]和next[1]的值肯定是0,因爲這時候不存在前綴子串;從next[2]開始,next數組的每一個元素都可以由上一個元素推導而來。

已知next[i]的值,如何推導出next[i+1]呢?讓我們來演示一下上述next數組的填充過程:在這裏插入圖片描述
如圖所示,我們設置兩個變量i和j,其中i表示“已匹配前綴的下一個位置”,也就是待填充的數組下標,j表示“最長可匹配前綴子串的下一個位置”,也就是待填充的數組元素值。

當已匹配前綴不存在的時候,最長可匹配前綴子串當然也不存在,所以i=0,j=0,此時next[0] = 0。

接下來,我們讓已匹配前綴子串的長度加1:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章