KMP的next究竟是什麼

2021-09-01 18:42:12 字數 1421 閱讀 2333

基於了解了kmp演算法,我們明白,當i和j對應的字元不相等時,我們不會對i進行回溯,而是呼叫了j=next[j],使j到達乙個位置,但是這個位置究竟是**,就需要進行一定的計算,在計算之前,先讓我們搞清楚這個next究竟是個啥?

對於上面的例子,i和j對應的字元不匹配,就需要j指向乙個新的地方,那是哪呢?

先看畫線的地方

首先i和j前面的兩個ab是匹配的,而模式串中前後都有ab,那麼可以利用這一點,將j移動到c的位置

如圖我們利用了上面描述的資訊,使得i不用進行回溯,而使j進行回溯,這樣會減少回溯的次數

next是什麼呢?我想大家心裡是不是有一點點想法了? 規定字串的第乙個字元下標為0,next[j]的值,就是j之前的字串中,字首子串和字尾子串相等時,最長的長度。例如上邊的例子,模式串s="abcabd";則,s4在它之前的字串是"abca",這個字串的字首子串和字尾子串相等的最長的子串是a,長度也就是1,所以next[4]=1,同樣,對於上面的例子即s[5]不匹配時,"abcab",前後相等的最長的子串就是ab,所以,next[5]=2

說了這麼多,大家應更明白了我的意思 我們當然可以使用統計字首子串和字尾子串的方式來計算next陣列的值,但是得不償失,因為我們使用kmp的目的時為了降低暴力窮舉所有子串的方法的時間複雜度,若使用統計子串的方式,時間複雜度可能會更高,所以用另一種方式來計算next陣列k是j之前的前後相等的最長字串的長度,因為字串從0開始,所以,k剛好指向了那個最長子串的後乙個字元,劃重點。。。所以,當k和j對應的字元相等時,也就是s[k]==s[j]的時候,j+1對應的那個最長子串的長度就是k+1,next[j+1]=k+1,也就是當j指向c時,k就會指向第二個a

接下來討論s[k]!=s[j]的情況

s[k]和s[j]不相等了,那麼,該怎麼辦呢,我們要讓k重新指到乙個地方,使得s[k]和s[j]相等,這樣,就可以使用上面的公式s[j+1]=k+1來計算,不能簡單地讓k--,直到找到s[k]==s[j]位置(這個的例子不是很好),例如abadabaad,當j指向最後乙個a時,k指向第乙個d,如果簡單的使用k--操作,k指向第二個a,也就是k為3,那麼,next[j+1]=k+1,也就是當j指向最後乙個d時,k指向了第乙個d,很顯然aba不等於baa,所以不能簡單的用k--來找k的位置

這裡其實又利用了kmp演算法

將包括k的前半段拿下來方便我們分析,這是不是很像主串和模式串的j和k指向的字元不同,接下來我們需要讓k=next[k]

int *getnext(char s)

//關於優化

for(j=1;j

return next;

}

Bundle 究竟是什麼?

bundle用於場景 在我印象中比較深刻的是,一般用於activity之間傳遞數值,也用於handler傳送訊息,如下 intent intent new intent bundle bundle new bundle bundle.putstring key value intent.putext...

分析EOF究竟是什麼

eof僅僅是一種狀態或者說條件,需要觸發。read呼叫遇到檔案結尾,觸發該條件,結果將返回0。針對eof,對於標準輸入裝置,普通檔案,管道檔案,網路套接字檔案是read如何觸發呢?下面程式將說明 server.c 是socket套接字服務端,目的為了網路套接字檔案是read如何觸發測試用的。serv...

分析EOF究竟是什麼

eof僅僅是一種狀態或者說條件,需要觸發。read呼叫遇到檔案結尾,觸發該條件,結果將返回0。針對eof,對於標準輸入裝置,普通檔案,管道檔案,網路套接字檔案是read如何觸發呢?下面程式將說明 server.c 是socket套接字服務端,目的為了網路套接字檔案是read如何觸發測試用的。serv...