先上**
class
solution
public
intkmp
(char
hayarr,
int haylen,
int neelen,
char
neearr)
if(hayarr[haypoint]
== neearr[neepoint])if
(neepoint == neelen)
}return-1
;}public
int[
]creatnext
(char
neearr,
int neelen)
if(neearr[k+1]
== neearr[i]
) next[i]
= k;
}return next;
}}
上面的**實現的next陣列記錄的是當前模式串的對應位置的前面最大相同字首的末尾所在的索引值。
並不是長度,所以我們需要減去1,即k的初始值為-1.
對於迴圈的選擇,可以選擇while,也可以選擇for這裡選擇for迴圈,有點遍歷的意思。因為這樣就可以可以把需要做的事情劃到每乙個模式串的值,這樣做無疑比while只有終止條件的那種情況下思路清晰的多。
我們具體來看對應的程式:
對模式串進行next陣列的構建,有兩種情況:
對應的字元相同
對應的字元不同
先來看不同的情況,如果不同的話,就需要往前去找,往前找的話可以從頭開始找,這樣時間複雜度是高的,那麼就在原來的基礎上,即前乙個字元的最大字首末尾所在位置去找,這樣就節省了時間。
然後是相同的情況,如果相同,那麼長度就+1,那麼記錄的next陣列對應的值也就+1.
至於為什麼是k+1而不是k,我們知道,next[0]的初始值就是k的初始值+1,next[0]為-1表示所在字首的下標是-1(這是人為規定的,也就是沒有,但是具體也是有意義的,看下面)。這裡我們操作的指標就是最大字首的末尾的下乙個字元,所以需要+1,而在需要向前回溯的時候,需要的就是看上乙個字元,所以不+1,但是這裡的回溯也是有限制的,當回溯到最前面的時候,就需要停止回溯,那麼回溯到最前面如果沒有條件限制會發生呢?陣列下標為-1,超出陣列的界限,這就是所謂的邊界條件。
同樣的,我們需要對每乙個遍歷到的主串的字元進行處理,所以還是用for魂環,這樣邊界清晰:不需要在while迴圈裡面新增if判斷語句,思路也清晰。
當兩個指標指向的字元不同的時候,根據kmp演算法,移動模式串的使得字首到字尾的位置,然後比較字首下面的字元,所以就是程式中所示。
字串KMP演算法思考
kmp演算法不是查詢最長公共子字串演算法,而是乙個判斷字串a是否包含字串b的更優的查詢演算法。kmp演算法的核心是next陣列的計算 最長相同字首和字尾的字串 比如abcdabd的next陣列是 1,0,0,0,0,1,2 kmp演算法查詢邏輯和獲取next陣列的邏輯非常相似,都是while迴圈裡面...
一點關於KMP演算法的思考
演算法用途 匹配字串。給定乙個模式串 pattern string ababc 乙個待匹配串 abababc 最樸素的方法就是兩層迴圈,從左到右依次比較,時間複雜度為o m n kmp演算法 給定乙個模式串 pattern string ababababc 觀察模式串 如果有乙個待匹配串是am,第2...
KMP演算法 關於各個步驟的疑惑和思考
1.為什麼只用研究模式串?因為發生不匹配時,模式串當前下標之前的內容和被查詢串的內容是相同的。2.為什麼移動方法不是下面的移動法1,而是移動法2?移動法1的思路是 既然原初不匹配情況下,當前位置之前有相同的字首 黃色和紅色 那麼可以直接在開頭跳過對紅色部分的檢索,因為黃色部分已經匹配了,紅黃相同就可...