串的模式匹配

2022-09-03 11:27:11 字數 3241 閱讀 6961

串的模式匹配

串的模式匹配即子串的定位操作,一般把要找的子串稱為模式串。

最普通的一種演算法思想大概如下:

從主串的第

pos個字元起和模式串的第乙個字元比較;

如果直到指向模式串的指標超出子串的長度,則匹配成功,否則匹配失敗。

為了避免語言上的歧義,也給大家乙個直觀的認識,下面找來幾幅圖描述了這種演算法的整個匹配過程。

第一輪(圖

第二輪(圖

第三輪(圖

第四輪(圖

1-4)(匹配成功):

這種演算法思想直接易懂,在很多情況下也有不錯的效率,然而,如果是像主串為「

0000000000000000000000001

」而模式串為「

0000001

」時就很浪費時間了,需要很多次的回溯,其時間複雜度最壞能去到

o(n*m)

kmp演算法

針對這種情況有一種很著名的演算法:

kmp演算法。其優點在於當匹配出現不同時,主串不是回溯到最開始,然後向後移一位,如圖

1-1,圖

1-2描述的那樣。而是直接根據部分匹配的結果,盡量使主串指標往右移,其效果就像下面兩幅圖展示的那樣。

第一輪:

第二輪:

假設主串指標為

i,模式串指標為

j時發生不匹配時,模式串指標需要變為

k。如上面那個例子,則第一輪時i為

5,j為

5,k為

2。那麼一般情況下這個

k根據什麼確定呢?

觀察上面的例子可以發現,

」t[0]t[1]…t[k-1]」=」s[i-k]s[i-k+1]…s[i-1]」

,這是由

k本身的意義決定的,因為主串指標為

i,模式串指標為

j時發生不匹配時,模式串指標需要變為

k,即是說模式串0到

k-1的字串必然與主串

i-k到

i-1的字串相匹配,且這個

k值盡量大。

另外,由於主串指標為

i,模式串指標為

j時發生不匹配,因此我們也可以知道

」t[j-k]t[j-k+1]…t[j-1]」=」s[i-k]s[i-k+1]…s[i-1]」

,因為模式串在

j之前的部分必然已經與主串相匹配了。

因此我們得到兩個

k要滿足的等式:

」t[0]t[1]…t[k-1]」=」s[i-k]s[i-k+1]…s[i-1]」

」t[j-k]t[j-k+1]…t[j-1]」=」s[i-k]s[i-k+1]…s[i-1]」

還有一些隱含的條件:

i>=j>k>0

,簡化後即

j>k>0;k

要盡量大。

根據兩個等式可以發現其實我們只需要關心模式串內部就可以了,即乙個等式:

」t[0]t[1]…t[k-1]」=」t[j-k]t[j-k+1]…t[j-1]」

(j>k>0;k

要盡量大)

其實從直觀上也不難理解,因為主串中對於得到

k值有用的資訊只是當前主串與模式串已經匹配上的那一段字串,而這段字串我們從模式串中同樣能得到,因此求得

k值可以簡化成模式串的內部問題。

另外,如果

j=0時,

k=-1

;找不到滿足條件的

k值時,

k=0;

令next[j]=k

,綜合起來就是:

-1(j=0時)

next[j]= max

0(其他情況

)kmp

演算法思想如下:

從主串的第

pos個字元起和模式串的第乙個字元比較;如果}

直到指向模式串的指標超出子串的長度,則匹配成功,否則匹配失敗。

而如何求得

next[j]

呢?首先

next[0]=-1

。設next[j]=k

,即滿足

max,

則next[j+1]

是什麼呢?

如果t[k]=t[j]

,則易得

max,即

next[j+1]=k+1=next[j]+1

。但如果

t[k]!=t[j]

怎麼辦呢?

其實我們可以把求

next[j]

的過程也看成乙個模式匹配的過程,只不過主串和模式串都是

t,而且目的是填上

next

表。因此

t[k]!=t[j]

時,我們也可以用

kmp演算法,使

t[j]

直接與t[next[k]]

進行匹配。

若t[j]= t[next[k]]

,則易得

max,即

next[j+1]=next[k]+1。若

t[j]!= t[next[k]]

,則同理類推,直到某個k值使

t[j]= t[next[k]]

,若沒有滿足條件的

k值,則

next[j+1]=0

。綜上,求得

next

表的演算法基本如下:

1

public

void getnext(string t,int

next)

1011

else

1213}14

15 }

串的模式匹配

最近在學 vc include stdafx.h include include define max size 1000 串的模式匹配 功能 找出str2字串在str1字串中第一次出現的位置 不包括串結束符 返回 該位置的序號 環境 visual c 2008 注意 1.此為樸素的模式匹配演算法,...

串的模式匹配

以前每次看到字串匹配,一律跳過,今天耐著性子研究了下,依舊是半混沌狀態,先整理放在這,以備後用。這篇文章幫助很大,樸素匹配演算法 kmp演算法,收藏先。1.樸素匹配演算法 int patternmatch common const char pstring,const char ppattern i...

串的模式匹配

子串的定位操作通常稱作串的模式匹配。index s,t,pos t被稱為模式串。直觀演算法 int index string s,string t,int pos else if j lent return i lent else return 0 直觀演算法很簡單,如果字串中當個字元匹配,主串指標...