/*<br />BM 演算法和 KMP 演算法一樣,也是構造一個輔助的模式函數來加速匹配的速度,<br />但BM演算法優於KMP。<br />SUNDAY 演算法描述:字串尋找演算法中,最著名的兩個是KMP演算法<br />(Knuth-Morris-Pratt)和BM演算法(Boyer-Moore)。兩個演算法在最壞情<br />況下均具有線性尋找時間。但是在實用上,KMP演算法並不比最簡單的c庫函數<br />strstr()快多少,而BM演算法則往往比KMP演算法快上3-5倍。但是BM演算法還不<br />是最快的演算法,這裡介紹一種比BM演算法更快一些的尋找演算法。<br />例如我們要在"substring searching algorithm"尋找"search",剛開<br />始時,把子串與文本左邊對齊:<br />substring searching algorithm<br />search<br />結果在第二個字元處發現不匹配, 於是要把子串往後移動。 但是該移動多少呢?<br />這就是各種演算法各顯神通的地方了,最簡單的做法是移動一個字元位置;KMP<br />是利用已經匹配部分的資訊來移動;BM演算法是做反向比較,並根據已經匹配的<br />部分來確定移動量。 這裡要介紹的方法是看緊跟在當前子串之後的那個字元 (第<br />一個字串中的'i')。<br />顯然,不管移動多少,這個字元是肯定要參加下一步的比較的,也就是說,如<br />果下一步匹配到了,這個字元必須在子串內。所以,可以移動子串,使子串中<br />的最右邊的這個字元與它對齊。現在子串'search'中並不存在'i',則說明可<br />以直接跳過一大片,從'i'之後的那個字元開始作下一步的比較,如下:<br />substring searching algorithm<br />search<br />比較的結果,第一個字元就不匹配,再看子串後面的那個字元,是'r',它在子<br />串中出現在倒數第三位,於是把子串向後移動三位,使兩個'r'對齊,如下:<br />substring searching algorithm<br />search<br />這次匹配成功了!回顧整個過程,我們只移動了兩次子串就找到了匹配位置,<br />是不是很神啊?!可以證明,用這個演算法,每一步的移動量都比BM演算法要大,所<br />以肯定比BM演算法更快。<br />*/</p><p>#include <iostream><br />#include <string><br />using namespace std;</p><p>void SUNDAY(char *text, char *patt)<br />{<br />register size_t temp[256];<br />size_t *shift = temp;<br />size_t i, patt_size = strlen(patt), text_size = strlen(text);<br />cout << "size : " << patt_size << endl;<br />for( i=0; i < 256; i++ )<br />{<br />*(shift+i) = patt_size+1;<br />}<br />for( i=0; i < patt_size; i++ )<br />{<br />*(shift+unsigned char(*(patt+i))) = patt_size-i;<br />}<br />//shift['s']=6 步,shitf['e']=5 以此類推<br />size_t limit = text_size - patt_size+1;<br />for(i=0; i < limit; i += shift[ text[i+patt_size] ])<br />{<br />if( text[i] == *patt )<br />{<br />char *match_text = text + i + 1;<br />size_t match_size = 1;<br />do<br />{<br />// 輸出所有匹配的位置<br />if( match_size == patt_size )<br />{<br />cout << "the NO. is " << i << endl;<br />}<br />}while((*match_text++) == patt[match_size++]);<br />}<br />}<br />cout << endl;<br />}<br />int main(void)<br />{<br />char *text = new char[100];<br />text = "substring searching algorithm search";<br />char *patt = new char[10];<br />patt = "search";<br />SUNDAY(text, patt);<br />return 0;<br />}<br />/*<br />size : 6<br />the NO. is 10<br />the NO. is 30<br />*/