串的模式匹配演算法 KMP演算法解析

2021-07-05 09:13:31 字數 2568 閱讀 1311

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 中存放的是串的...