這兩天呢,一直在被小夥伴們快ak的恐懼支配,g題杭電的資料很水,但是自己還是選擇不水過,用擴充套件kmp去寫,網上的資料很多,自己選了乙個最簡潔的模板,不用再寫乙個求next陣列的函式,直接呼叫前特殊處理下exkmp函式就既可以求next陣列,又可以求ex陣列啦,hh誰說魚與熊掌不可兼得,這不就是嗎~但是呢,一開始一點也不好理解哎,自己選的模板,跪著也得理解完~~~(淚目~~
————言歸正傳,總結——————
1.擴充套件kmp演算法呢是對kmp演算法的擴充套件,擴充套件kmp演算法也有乙個和kmp函式名字一樣的next陣列,還有乙個ex陣列。
2.擴充套件kmp演算法的可以用o(m+n)的複雜度求出字串s1任意字尾和字串s2的最長公共字首。
3:擴充套件kmp演算法裡ex陣列:ex[i] == j表示s1
以i為起始的字尾與s2的最長公共字首。
擴充套件kmp演算法裡next陣列:next[i] == j表示s2以i為起始的字尾與s2的最長公共字首
兩者作用都一樣當然可以呼叫同乙個函式咯~
kmp演算法裡next陣列:next[i] == j表示s2在0~i之前已匹配的字首字尾長度為j+1(前提是next[0]初始化為-1,如果初始化為0,已匹配的長度就為j)
————加深理解,模擬演算法實現過程————
用樣例s1=aaaabaa,s2=aaaaa直接進行模擬演算法實現過程,前提是要結合模板
第一步:由於exkmp函式的作用是在已知s2的next陣列的情況下,求出字串s1的任意字尾與字串s2的最長公共字首,存入ex,所以我們需要先呼叫函式求出next陣列
主函式裡呼叫過程如下,預先初始化next[0]=0;
exkmp(s2+1,s2,next+1,next);
這樣呼叫的原因參見總結3,生成next陣列的過程相當於將s2與s2自身進行匹配,s2+1 == 形參s1
s2 == 形參s2
next+1 == 形參ex
next == 形參next.
接收過程如下:
void exkmp(char s1,char s2,int ex,int next)
a.在此函式中我們傳遞給形參s1的是s2+1,結合下圖所示樣例s1=aaaa,s2=aaaaa來看,即s1[0..] == (s2+1)[1..]
b.傳遞給形參ex的是next+1,也就是next陣列後移一位,即ex[i] == next[i+1](有點難懂,解釋下,
我們將形參s1和形參s2進行匹配時,實際就是實參陣列s2[1...]的字尾與實參陣列本身s2[0..]的字首進行匹配,所以我們匹配出的最大公共長度min(next[j],p)賦值給形引數組ex[i]時,實際就是賦值給next[i+1],(這裡不知道為什麼取最小值不要緊,稍後進行解釋),結合下圖兩張來看,明顯e陣列的值存入next陣列的後一位。
第二步:在已知s2的next陣列的情況下,再次呼叫函式,求出s1的任意字尾和s2的最長公共字首,存入ex。
在函式呼叫過程中,我們比較s1[i..]與s2的最長公共字首部分時,只取較小的值,原因是,只有s2的自身字首長度與p(s2和s1的公共字首長度)都是公共長度的時候,這個值才能保證就是s1[i..]與s2的最長公共字首部分。
當它們相等時,無法直接比較判斷出最長公共字首部分,因為p之後也有可能有公共長度,所以我們只需要繼續從p開始逐一比較。
/*主函式裡初始化和呼叫*/
/*next[0] = 0;
exkmp(s2+1,s2,next+1,next);
exkmp(s1,s2,ex,next);*/
void exkmp(char s1,char s2,int ex,int next)
else if(next[j] < p)
ex[i] = next[j];
else if(next[j] > p)
ex[i] = p;
else
i++;
j++;
p--;
} ex[i] = 0;
return;
}
字串專題 擴充套件KMP
思路 乍一看就是擴充套件kmp,但這題還是要一點點轉化。如果想要滿足題目要求,匹配段肯定間隔是相反的。比如樣例中在0位置匹配 1 3 4 2 6 9 5 3 2 2 0 code include using namespace std const int ax 1e5 66 int n m int ...
( 字串專題 ) 擴充套件KMP
字串專題 擴充套件kmp 時間複雜度 o n m 用 extend i 表示t i n 1 與p的最長公共字首。假設t aaaab p aaaa 則extend 5 next i 表示為 串p 中以 i 為起點的字尾字串和 整個串p 的最長公共字首長度.假設p aaaab 則next 5 模板 in...
字串 KMP演算法
而kmp演算法在字串匹配方法中乙個很著名並且很聰明的演算法,當然也確實比較難理解。甚至於有程式設計師因為無法理解kmp演算法而直接改用暴力匹配。本身自己學演算法起步較晚,第一次接觸到kmp演算法已經是研究生畢業一年了。雖然帶著研究生的學歷背景,但是剛開始看的時候依然是一臉懵逼。看了很多博主的講解總算...