kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。首先我們生成match字串的next陣列,next[i]的含義代表的是match[0…i]中,必須以match[i]結尾的字尾子串(不能包括match[0])與必須以match[0]開頭的字首子串(不包括match[i-1])最大的匹配長度。
>
void getnext(const char *p,int
next)
next[0]=-1;
next[1]=0;
intpos=2;
int cn=0;
while(pos
if(p[pos-1]==p[cn])
else
if(cn>0)
else
next[pos++]=0;
}}
但是,我們仔細考慮這麼一種情況,abababc,此時的next陣列為 -1 0 0 1 2 3 4。當i為3的時候,也就是說next[3]=1,此時我們要回退到第乙個b那裡去,然而此時我在i上的值就是b,換句話說要匹配的不是b,再回到第乙個b那裡去比較也沒有意義,所以我們需要加乙個判斷,這樣會讓我們的next陣列跳躍的更快。原先的情況只是考慮i為結尾但不包括i,這裡我們把i也考慮了進去。因此,我們將之前的if判斷再加上乙個判斷即可。
if(p[pos-1]==p[cn] && p[pos]==p[cn+1]) //如果發生了上面的情況,直接看要跳過去的next就行了。
else
if(p[pos-1]==p[cn])
這裡假設我們已經求出了next陣列,我們從str[i]出發,匹配到了j位置的字元發現與match的字元不一致了,也就是說,str[i…..j-1]和,match[0……j-i-1]是同樣的,但是str[j]!=match[j-i]。這個時候就需要回退。
此時我們已經有next陣列了,next[j-i]的值 表示的是 match[0……j-i-1]的最大匹配。所以現在回退不需要回退到開頭,只需要讓str[j]與match[k]比較.
void kmp(const
char t,const
char p,int next)
if (p[q] == t[i])
if (q == m)
}
}
經過測試,比較次數是小了那麼一點點~
在當前用於查詢子字串的演算法中,bm(boyer-moore)演算法是當前有效且應用比較廣的一中演算法,各種文字編輯器的「查詢」功能(ctrl+f),大多採用boyer-moore演算法。比我們在學習的kmp演算法快3~5倍。
BF演算法和KMP演算法
今天資料結構學習了兩個字串匹配演算法,bf演算法和kmp演算法。課本講的過於籠統,不能理解kmp演算法,因此在網上找些資料後整理筆記如下。字串匹配演算法就是在文字串中匹配模式串。bf brute force 演算法即暴力演算法。從第乙個字元開始匹配,每當匹配失敗時,模式串向右滑動一位。最後返回第一次...
BF和KMP演算法
字串匹配演算法 include include using namespace std define ok 1 define error 0 define overflow 2 typedef int status define maxstrlen 255 使用者可在255以內定義最長串長 type...
字元 BF 和 KMP演算法
kmp演算法是一種改進的字串匹配演算法,由d.e.knuth與v.r.pratt和j.h.morris同時發現,因此人們稱它為克努特 莫里斯 普拉特操作 簡稱kmp演算法 在介紹kmp演算法之前,先介紹一下bf演算法。一.bf演算法 bf演算法是普通的模式匹配演算法,bf演算法的思想就是將目標串s的...