字串匹配是編程常用的技巧之一,特寫此博文,一則深入學習之,二則作為一種積累,三則秉承“NO matter whether it is right,show my code and confirm the result”原則。
前段時間 ,也在csdn上看到了一篇 ,但感覺那是高手層級的手法,看起來著實讓人不知所以然。
由於本人水平屬於菜鳥層級的,極盡簡單的語言,力求理解。紕漏之處,請指正!!
最簡單的匹配莫過於蠻力法了,直接挨個遍曆,演算法複雜度O(m*n),老規矩 先上代碼:
#include"iostream" using namespace std; int SearchStr(char * mStr,char * patternStr);//declare function int main() {cout<<SearchStr("qwer","we"); } int SearchStr(char * mStr,char * patternStr)//返回模式串的位置,否則返回-1 { int i=0; int j=0; int mStrLen=0; int patternStrLen=0; while(mStr[i]!='\0')//擷取目串的長度 {++i;} mStrLen=i; i=0; while(patternStr[i]!='\0')//擷取模式串的長度 {++i;} patternStrLen=i; for(i=0;i<=mStrLen-patternStrLen;++i) { while(j<patternStrLen && (patternStr[j]==mStr[j+i])) { j++; } if(j==patternStrLen) return i+1; } return -1; }
測試結果:
原理很簡單:在母串中依次與模式串中的字元比較,直至模式串結束,若在結束前發現存在字元不匹配的情況,則停止匹配,母串右移一位,模式串回到第一個字元,然後重 新開始匹配。
如果在文本中尋找這樣的字串,當文本很大時,對效能的影響還是很大,這個很大是相對於我們已有的其他匹配演算法的效能而言的,任何技術都是在比較中才能找出其優劣。下面談談KMP演算法的原理,至於其來源,網上一大堆,大家隨手一搜就能找到,不再廢話。
KMP看似複雜,其實也不難,網上有很多關於它的文章,但是大多晦澀難懂,特別是 清華 嚴蔚敏的書 一堆數學公式,直叫蛋疼。
KMP演算法的本質就是匹配的次數比蠻力法更少了,其跳過了很多匹配,依據就是利用以前的匹配殘留的資訊。比如:
要在 a b e d d a b e a b 中尋找 a b e a b,如果根據蠻力法,則依次比較
但是很明顯:在母串中:a(母)!=b(母) b(母)!=e(母);同理:a(模)!=b(模) b(模)!=e(模);而a(母)=a(模),b(母)==b(模) ,e(母)==e(模)(我們已經匹配的3個字元,當然相等),簡答的數學代換:a(模)!=b(母),其餘倆個類似。既然如此,就沒有匹配的必要了。模式串直接移到母串的第3個位置。如:
如次一來,是不是比較的次數就少了。KMP的大致原理就是這樣。根據此原理,最壞的情況下時間複雜度為O(m+n),而蠻力法為O(m*n),也許當m,n很小是差別不大,但是如果m,n很大 差距就出來了。
根據此演算法,KMP的關鍵就是得知道每次移動的次數,這個本人菜鳥級的,吃得不是很透,但是萬幸找到了一個更細點的部落格。直接轉接:http://billhoo.blog.51cto.com/2337751/411486 http://www.ruanyifeng.com/blog/it/algorithm/