剛剛寫了點
我剛剛除錯了幾次 ,然後又在自行輸出 。 我先說說 啊,就是這個 next 陣列就為什麼可以求出前字尾最長 相同的數量? 首先說說 前字尾,例如字串 aaaa,我們就直接用眼睛看的話,就是最長就是3,aaa a ; a aaa。 這就是最長的前字尾,我們怎麼用**實現的呢? 首先 前字尾 不能是一樣的 (就如這個前字尾 不能是 aaaa,aaaa 這就不是前字尾了) ,所以說,最長的肯定是 (在相同的情況下,i和這個j 數量相差1 的時候,我想這就是 i初始設定為0,j初始為-1,數量相差1,這應該就是在這種情況下最長的了 )。。。
下面 看其他的情況 ,就是 上面那種情況和這種情況也是,當 i和 j 之間相差 1時,這個就是前字尾數量最長的時候了(但不一定前字尾相同,只是在這裡說一下),一開始 i=0,j=-1 ,我們就開始 以這個 最長的前字尾數量 開始 ,如果 s[i]!=s[j],我們就開始跳轉了,i和j之間的距離逐漸拉大(但是也有限制的,直到 j==-1的時候,就停了) ,逐漸拉大的意思就是 從前字尾數量 最大逐漸減小,看看這時候前字尾 比較 s[i] s[j]的關係,如果還不行,我們就繼續跳轉,(好像跳轉都會一直將j跳到 -1 去)。如果j 到了 -1,還沒有,我們就只能 將 i++,j++,這個意思好像就是 中間這段我們已經沒有利用價值了,再怎麼減少前字尾數量,都不能形成相同前字尾了 。(所以在每次 跳轉到 j==-1時 ,next[i]=j ,這個意思好像就是 這前面的這段 沒有前字尾相同的,(可能前面有相同的,但是前面一直到這裡是沒有的),有點像dp狀態轉變,每個點都是乙個狀態點好像 )。這樣就開始了新的一輪前字尾數量查,與前面一樣。
對了,還得補充一點,就是上面所說的,每個點就好像是乙個狀態,與前面經過的點和後面的點沒有什麼太大的關係。所以在每次 aaa,s[i]==s[j]的時候,就都會next[i]=j; 這個 j因為做了j++ 操作 ,所以就是前字尾相同數量。 每個點 都會有乙個狀態。就像 aabbaa 在 ab 這裡斷的時候,就會j跳轉到-1 處,重新來,結果發現還是 a b 矛盾,沒有辦法,在逐漸減到 -1,再來 ,這時 就是 a a,就這樣 配下去了。更新next 陣列。
所以說 ,我感覺next 奇妙之處,前後點的狀態不受影響,自己有自己的狀態,互不影響。
還有,一開始看不懂,就去 看 它怎麼去找的前字尾 (到底是怎麼去找的,就沒有太注意i 和 j 之間 距離的變化,我感覺 i 和j之間 挨的越近,前字尾數量就越多(只是前字尾相同情況),一開始 從相隔1 (相對的,有的相隔不是1), 到相隔越來越大(不相同的情況)(相對的)。 )。
說了這麼多,希望對你有點 幫助
我放出測試**:
#include#include#include#include#include#includeconst int maxn=1000005;
using namespace std;
#include#include#includetypedef long long ll;
int anext[maxn];
void getnext(string s)
{ int i=0;
int j=-1;
anext[0]=-1;
while(i"<"<";
j=anext[j];
cout《如有出入,請不吝賜教,互相學習。
KMP next陣列的求法
kmp 演算法的next陣列求法 void getnext char ptn,int next next j 更新自己的值。如果 1 j ptn i ptn j 這個條件成立,此時可以計算next i 1 的值為j 1。我看看這個過程 當i 6進入while迴圈之前,j next 6 當i 6進入w...
KMP next陣列理解
3.15週末學長教了一下kmp,但是對next的構造尚存疑.在饒了一整天頭以後勉強弄懂了 記錄一下比較混亂就是了 這裡的對稱指的的字元塊對稱而非軸對稱 當next t 值為0時 顯然就意味著從字串的開頭到這個t部分的話對稱性是0 即當繼續計算下一位的next t 1 的大小時只需比較第n 1位的字元...
KMP next陣列的花式使用
kmp演算法,是用來優化字串的模式匹配 源串s中是否存在模式串p 可以把暴力匹配的複雜度o n 降低到o m n 通過對模式串生成字首陣列 next陣列 來跳躍式的進行模式匹配,解決如hdu 1711 這樣的問題。我們一般使用的是把next 0 標記為負數 1 的修正版kmp。但是kmp演算法中最具...