kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。
具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。
要想知道kmp的高效性在**,我們就首先需要了解常規演算法。
text:需要被查詢的文字
pattern:需要被匹配的字元
我們還是先看看偽碼應該怎麼寫。
*****-string-matches(t,p)
n<- length(t)
m<-length(p)
for s<-0
to n-m
doif p[1
--m]=t[s+1--s+m]
print s
這裡的下標都是從1開始,這樣也更符合我們的思考
#include
#include
using
namespace
std;
int match(const
string& target,const
string& pattern)
else
}if(pi==p)
return ti-pi;
else
return -1;
}
首先我們先定義一下什麼是next陣列;
next陣列——覆蓋函式子串
值a-1ab
-1aba
0abaa
0abaab
1abaabc
-1abaabca0
如果不解釋,你是否能看得出其中的規律?
就是
用通俗的話來講,pattern的前k個字元和最後k個字元相同。如何獲得這一next陣列
我們如果仔細分析,那麼發現,這其實可以用遞迴式來表示。
注意,這裡我們使用的是overlay名稱來代替next這一稱呼
#include
#include
using
namespace
std;
void computer_overlay(const
string& pattern)
if (pattern[index + 1] == pattern[i])
else
}for (int i = 0; i < pattern_length; i++)
這樣我們就得到了next陣列(overlay)。
next的意義在於,我們在樸素演算法中匹配失敗時,需要將ti降到即ti-pi+1的位置上去,並且將pi降低到0。
現在,我們根本不需要這麼做,將pi降低到index[pi]就可以了。
#include
#include
using
namespace
std;
//kmp演算法 尋找乙個字串在另乙個字串中的位置
int kmp_find(string& target, string& pattern)
if (pattern[i] == pattern[index + 1])
overlay[i] = index + 1;
else
overlay[i] = -1;
}for (int i = 0; i < pattern.size(); i++)
//進行比對
int ti = 0, pi = 0;
while (pi < pattern.size() && ti < target.size())
else
if (pi == 0)
else
}if (pi == pattern.size())
return ti - pi;
return -1;
}int main()
其中,這一段顯得很突兀。
else
if (pi == 0)
但是,這一段卻很重要,因為所有overlay[i]==-1的i值最終都會指向0。
如果此時pattern[0]!=target[ti],那麼唯一的選擇就是ti進一位。
也就是說,kmp演算法中,在無法匹配當前pi和ti時,除了將pi=overlay[pi-1]+1之外,在特殊的情況下,所需要的是ti++。
說到這裡,我們還是對kmp演算法做乙個總結吧。
總體來說,這個演算法很精妙,尤其是overlay陣列(next陣列)的建造過程也很漂亮的乙個地方。
kmp的核心實在target[ti]和pattern[pi]失配時,pi的平移並不是暴力地回到0處,ti也不是到達上一次起點+1也就是ti-pi+1的位置。
這樣就節省了大量的時間。
解析KMP模式匹配演算法
程杰 大話資料結構 那本書中,串 那一章的最後有個特別厲害的演算法 kmp模式匹配演算法。模式匹配演算法其實就是,在乙個主字串當中尋找某子字串,並返回子字串在主字串中的位置。這個kmp模式匹配演算法可真的是狂拽酷炫吊炸天,核心 僅僅四五行,而我看了兩個多小時才看明白 允許我在這裡賣弄一下我的 笨 k...
串的模式匹配演算法 KMP演算法
這個演算法理解起來有點難受,建議看下簡單的串模式匹配演算法bf演算法刷下經驗,如上鏈結。相比於brute force bf演算法 每當一趟匹配出現字元不等時,不需要回溯i指標 目標串指標 並且模式串指標j將從已經得到的部分匹配模式盡可能後移,從而降低時間消耗。o n m bf演算法為o n m 對於...
演算法 串的模式匹配演算法(KMP)
串的模式匹配演算法 問題 求子串位置的定位函式如何寫?int index sstring s,sstring t,int pos 給定串s,子串t,問t在s中從pos位開始第一次出現的位置是?我沒有使用字元陣列或者string,而是自己實現sstring,這其實是資料結構作業 s 0 中存放的是串的...