字串匹配之樸素演算法和萬用字元擴充套件

2021-04-20 08:29:39 字數 2747 閱讀 7183

【字串匹配】:給定乙個

t[1..n],p[1..m] ,t和p

中的任意元素屬於∑(有限的字元集合),求位移s使得

t[s+1..s+m] = p[1..m].t

代表text(

文字串), p

代表pattern(

匹配串).

有多種演算法可以實現

,這裡只介紹最簡單

,最容易理解

,」最笨的

」 樸素匹配演算法:

t:t1 t2 ….tn p

:p1 p2..pm

其中(m<=n)

最容易想到的就是讓p在

t上乙個字元乙個字元的向右滑動,然後比較

t的某一段時候和

p想匹配,若不匹配,繼續向右滑動;否則匹配成功。這樣效率比較低,最壞情況下複雜度為

theta((n-m+1)*m)

。偽**如下:

n <- length[t]

m<- lengthp[p]

for s=0 to n-m

if t[s+1…s+m] = p[1…m]

匹配成功,輸出

s,若只匹配第乙個,則可在此退出迴圈。

else

繼續匹配

對於有限的字符集下(假設個數為

d),若果t和

p中的字元都隨機出現,則平均比較次數為(

n-m+1

)*(1-d^-m)/(1-d^-1) <= 2(n-m+1)

。呵呵,

這樣看來這個「笨」的演算法還算可以,不算很「笨」。

下面給出一種用回溯方法寫的**:(和

strstr

函式功能相同)

int index(const char * str1, const char * str2, size_t pos)

else// unmatched then backtrace

} if(j >= strlen(str2))// matched and return the index

return i-strlen(str2);

else

return -1;// not found }

舉個例子就一清二楚了。

t =aababcd

p =abc第1

次: a a b a b c d

a匹配成功

,繼續下個字元的匹配,第2次:

a a b a b c d

a b匹配失敗,回溯,進行第3次:

a a b a b c d

- a

匹配成功,繼續….

歸納下看:第m

次: 先假設陣列開始的下標為0。

t=o o …o o o o o o o

p=o o o o …與p

的第乙個字元的下標為

0,正在匹配的下標為

j,此時與

p[j]

匹配的t

的下標是i。

1)若p[j]

與t[i]

匹配,則繼續下乙個字元的匹配,

i++,

j++。 2)

若p[j]

與t[i]失配,

則t的下標回溯到

i-j+1,p

重新開始(

j=0)。

若陣列下標不是以

0開始的,而是以一開始的,只需回溯到

i=i-j+2

,j=1

即可。

【擴充套件】加入匹配字串中有萬用字元

*,?。

*可以匹配多個字元,多個連線在一起的

*可以認為是乙個,而

?只能通配乙個字元。則演算法可以改進為: 當

p[j]

是』*』

時,求t

與p[j+1]

匹配的第乙個字元所在的下標,

t的下標置為此值。然後繼續迴圈。哈哈,語言描述能力不行啊,還是直接看**吧:

/**decrip:match the string('*' and '?' not included) with pattern including *(se

*        veral),?(only one)

*input:

*    t  --  text 

*    p  --  pattern

*return:

*     true for exit ,false for not

*     start,end -- the index of the pattern found in the text 

*/bool match(const

char* t, const

char* p, int& start, int& end)

if(t[i] == p[j] || '?' == p[j])

++i;

++j;

if(j == m) // match finish

end = i-1;

}else

// unmatched ,then backtrace(start a new loop)

}if(j >= m)  // succeeded to find the pattern

else

return

false;}

【備註】

1)以上內容,樸素演算法偽**參考《演算法導論》。

2)回溯程式是看了一位網上哥們的偽**寫的。

3)萬用字元擴充套件是參考1),

2),自己分析寫的。

樸素字串匹配演算法

include include include define maxsize 40 define ok 1 define error 0 using namespace std typedef char string maxsize 1 int string assign string m,char...

演算法 樸素字串匹配

模式匹配是資料結構中字串的一種基本運算,給定乙個子串,要求在某個字串中找出與該子串相同的所有子串,這就是模式匹配。假設p是給定的子串,t是待查詢的字串,要求從t中找出與p相同的所有子串,這個問題成為模式匹配問題。p稱為模式,t稱為目標。如果t中存在乙個或多個模式為p的子串,就給出該子串在t中的位置,...

樸素的字串匹配演算法

乙個字串是乙個定義在有限字母表 上的字串行。例如,abcdabc是字母表 上的乙個字串。字串匹配問題就是在乙個大的字串t中搜尋某個字串p的所有出現位置。其中,t稱為文字 或稱主串,模式串 p稱為模式 或稱子串 t和p都定義在同乙個字母表 上。設文字為長度為n,用字元陣列t 1.n 表示,模式串長度為...