【字串匹配】:給定乙個
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 表示,模式串長度為...