字串的精度匹配就是在文字t中找出模式p的精確副本,並求出匹配的位置下標。即如果p[0...m-1]==t[k...k+m-1] ,則稱p與t的子串行匹配成功。我們要找出所有匹配成功的k。
樸素字串匹配方法很簡單。從文字t的第乙個字母和模式p的第乙個字母開始比較。如果不匹配,就從t的第二個字母開始匹配,依次類推,不保留所有有用得資訊。設p和t的長度分別為m和n .這種演算法有兩層迴圈,沒有預處理時間,演算法時間複雜度為o(nm)。
void *****_string_match(string t, string p)
}
其中postion陣列儲存了匹配成功的 k 值。
另外一種改進的辦法叫做rabin-karp演算法。這個演算法在實際應用中可以較好的執行。rabin-karp演算法預處理時間是o(m) .平均執行時間是o(n)(m<=n),在最壞情況下執行時間為o(mn) .首先在初等數論中有以下結論 :
設 a,b,q為3個正整數,則有:
1)(a+b) mod q= (a%q+b%q)%q
2)a×b mod q =(a mod q)×(b mod q) mod q
設組成t和p的字元組成的集合是 a,例如a= .則a中字元的個數記為 |a| .演算法的核心思想是將模式p通過乙個hash函式對映為乙個整數值 ,也將於p匹配的那部分t[pos...pos+m-1]對映為乙個整數值,如果hash[p]!=hash[t]則他們一定不匹配,但是如果hash[t]==hash[p]則不一定匹配,這時候需要乙個乙個字母的比較。至於計算hash[p],我們可以通過霍納法則來求,時間為o(m).
而對於hash[t]的值,我們需要開始計算出t[0...m-1]的值h(0),在計算h(t)時不需要重新計算,可以通過h(t-1)獲得:
h(t)=((h(t-1)-t[pos])*|a|^m)*|a|+t[pos+m] )mod prime;
這個式子使用的|a|進製,同時需要乙個素數作為模運算。在一開始就可以把中間|a|^m計算出來,於是可以不用每次都計算|a|^m.具體**如下,選擇的是a=,即26進製:
#include#includeusing namespace std;
#define p 82595483
void match(string w, string t);
int postion[1001];
int ans;
int main()
void match(string w, string t)
while (pos <=n-m)
h = (26 * h - (t[pos] - 'a')*d + (t[pos + m]-'a')) % p;
pos++;
}}
樸素字串匹配演算法
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 表示,模式串長度為...