資料結構之字串的模式匹配

2021-07-04 20:28:14 字數 1953 閱讀 9908

字串的模式匹配問題:

一共有兩種演算法,

1.樸素模式匹配演算法。

舉例而言(尋找從s=」goodgoogle」中找到v=」google」這個子串):我們一般需要以下的步驟

(1).從主串的第乙個字元開始,s與

v中的字元逐一比較,可以發現前三個匹配成功而第四個沒有匹配成功(豎線代表成功,折現代表失敗)。

(2)主串的開始下表+1

,又繼續與子串進行匹配

(3)如果沒有匹配成功那麼繼續重複第二步,直到全部匹配成功,或者直到s到達末尾匹配失敗。

實現**:

//返回子串t在主串s中第pos個字元之後的位置。若不存在,則函式返回值為0.

//t非空,1<= pos <=s.length

public int ndex(string s,string v,int pos)else

}

對於上面的演算法,我提出一些改進意見就是,匹配的終止條件可以具體一些,減少迴圈的次數。當主串的剩餘子串長度小於要尋找的子串長度時,就可以停止匹配了。

可以在while中比較兩個字串相等位置的**之前,加乙個大的判斷

if(s.length-1 - i 

,如果滿足條件直接

break

,跳出迴圈,後面的字元可以不用比較。

2.kmp模式匹配演算法(是對

1演算法的改進)。

假如有主串 s= 「abcdefgab」;  匹配子串

:t=」abcdex」;我們使用上面的樸素匹配法過程如下。

如果我們認真觀察其實可以發現②③④⑤步驟是不需要的,是重複的無用操作。因為我們可以發現對於子串的首字元a

並不與後面任意乙個字元相等,並且如果出現①中的這種現象,子串的前

5個字元與主串相等,那麼就意味著子串

t不可能在於主串s中的

2-5號字元相等,

2-5號操作是多餘的。這就是

kmp演算法改進樸素演算法的地方。

kmp模式匹配演算法的核心是:如果我們知道子串

t的首字元與

t中後面的字元均不相等(這是前提),如果在出現如①的情況,即子串的前部分與主串的前部分字元相等,但是從

i號不相等,那麼我們可以斷定以

2 到 

i-1號任意乙個字元開頭的字串不可能與子串匹配成功,那麼主串的

2 到 

i-1號不需要進行判斷,直接從

i號開始判斷。

如果子串中有與首字元重複的子符,該怎麼辦?我們以s=」abcabcabc」 t=」abcabx」為例說明。首先繼續樸素匹配演算法。

因為首字元a有重複,我們不能繼續運用上面的規則,但是我們可以發現,到第二個出現首字元之前的字元我們是可以使用規則,將其規避掉,即②與③去掉,不要判斷。

因此:對於子串中有與首字元相等的字元,可以省略掉一部分不需要的判斷。

這裡如何判斷與首字元相同的不同位置字元,對演算法的影響,參考《大話資料結構》p139.

資料結構 字串 模式匹配

我們先把模式串標出序號 接著把模式串所有字首依次列出來 接下來把每乙個子串相等的字首和字尾的最大長度求出,舉個例子 abaab 觀察子串,前字尾ab相同,因此返回2 5.依次類推,我們可以得到每乙個子串對應的一組序列 當時這組資料並不是所要求的next陣列,可以將其稱為部分匹配值表,相應c 如下 獲...

資料結構 字串的模式匹配

什麼叫做模式匹配呢?其實就是看字串s中是否有子串t,那麼t就叫匹配串。我們平時查詢方式是逐個匹配,那麼時間複雜度就是o n m 比如s abcabde t abd 那麼比較的時候s 1 t 1 所以接下來比較s 2 和t 2 結果s 2 t 2 那麼接下來就比較s 3 和t 3 這一次比較匹配不上。...

資料結構 字串匹配

演算法 如下,包括暴力匹配和kmp演算法。參考 include stringmatching.h stringmatching stringmatching void stringmatching stringmatching void 返回子串t在主串s中第pos個字串之後的位置。若不存在,則返回...