KMP next陣列優化的思路徹底解析

2021-07-16 14:58:46 字數 1963 閱讀 5406

首先我們假設各位都已經了解了next陣列的作用,在這裡我們的next陣列記錄的是該位置之前的子模式串的最長公共前字尾

非常淺顯易懂的kmp演算法講解

那麼我們優化的思路就來了:

這點優化的思路在於假設模式串中q號位置失配了,那麼我們下一次要跳轉到next[q-1]號位置進行匹配,但是如果pattern[q]==pattern[next[q-1]]的話,那麼我們這一次的匹配還是失敗的,我們需要繼續我們的next迭代過程,知道找到開始匹配的為止

那麼我們為什麼不能再next陣列的求解過程中就提前優化好呢,這一點就是優化的思路,我們既然還有再次呼叫next陣列,還不如讓next[q]=next[next[q-1]],這就是優化的思路

但是我們可以很明顯的發現,在我們的kmp函式中,我們的語句while(j>0&&pattern[i]!=pattern[j]) j=next[j-1];我們突然發現這句話的思路和kmp的next陣列上述優化的思路是一致的,但是我們會發現,如果我們提前將next陣列的優化確定下來的話,我們對於這種多次的迭代(被優化的部分)的過程只用進行一次,下一次就是常數時間的o(1)時間的呼叫,但是如果我們不對next陣列進行優化,而只是決定依靠我們kmp函式中的那句話來進行我們的迭代過程,我們碰見一次就要迭代一次,原本我們可以一次求出直接用的方式就變成每次用都要求一遍,這樣子的話,kmp 的速度就會大大降低,所以說,我們決定直接對next陣列進行優化,反而還節省了大量的時間,並且我們在這樣優化next陣列的過程中時間複雜度並沒有上公升,時間複雜度是沒有變的,所以說,但是不優化,頻繁呼叫迭代的next會使我們的複雜度大幅度上公升

作為例項,下面是我封裝的**,在**中還有更詳細的解釋:

#include"iostream"

#include"cstdio"

#include"cstdlib"

#include"cstring"

#define n 100

using namespace std;

templateclass kmp;

templateistream& operator>>(istream&,kmp&);

templateostream& operator<<(ostream&,kmp&);

templateclass kmp

friend istream& operator>><>(istream&,kmp&);

friend ostream& operator<<<>(ostream&,kmp&);

void getnextone(); //未優化的

void getnexttwo(); //優化過的

void find();

private:

t pattern[n];

int plength;

t mother[n];

int mlength;

int next[n];

int fpos;

};templateistream& operator>>(istream& in,kmp& k)

templateostream& operator<<(ostream& out,kmp& k)

}templatevoid kmp::getnexttwo()

}templatevoid kmp::find()

{ int i=0;

int j=0;

getnexttwo();

for(;i0&&pattern[j]!=mother[i]) j=next[j-1]; //其實這一句話和next陣列的優化思路是一致的

if(pattern[j]==mother[i]) j++;

if(j==plength)

{ fpos=i-plength+1; //j-fpos+1=k.plength

cout<<"我們找到了匹配的模式串,第一次出現的位置在"cin>>my;

my.find();

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 陣列的思想

剛剛寫了點 我剛剛除錯了幾次 然後又在自行輸出 我先說說 啊,就是這個 next 陣列就為什麼可以求出前字尾最長 相同的數量?首先說說 前字尾,例如字串 aaaa,我們就直接用眼睛看的話,就是最長就是3,aaa a a aaa。這就是最長的前字尾,我們怎麼用 實現的呢?首先 前字尾 不能是一樣的 就...

KMP next陣列的花式使用

kmp演算法,是用來優化字串的模式匹配 源串s中是否存在模式串p 可以把暴力匹配的複雜度o n 降低到o m n 通過對模式串生成字首陣列 next陣列 來跳躍式的進行模式匹配,解決如hdu 1711 這樣的問題。我們一般使用的是把next 0 標記為負數 1 的修正版kmp。但是kmp演算法中最具...