串的模式匹配
串的模式匹配即子串的定位操作,一般把要找的子串稱為模式串。
最普通的一種演算法思想大概如下:
從主串的第
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
表的演算法基本如下:
1public
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 直觀演算法很簡單,如果字串中當個字元匹配,主串指標...