字串匹配演算法

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   for   ar   

今天一天鼓搗了兩種字串匹配的演算法,KMP演算法和BM演算法,說實話,BM演算法還是第一次聽說,以前只知道BM演算法的說,總之一句話,要學習的還是很多的,看了BM演算法,只能感歎作者的高大上了。看了好幾篇文章,終於算是把BM演算法實現了,並且調試運行成功了,把這學習的經過記錄下來,聊表紀念。

  1 #include <iostream>  2 #include <string.h>  3 #include <stdlib.h>  4   5 using namespace std;  6 //字串匹配演算法,普通的雙字元掃描演算法不多講效率很慢O(m*n)的複雜度  7 //下面主要講述的KMP演算法和BM演算法  8 //http://www.searchtb.com/2011/07/%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D%E9%82%A3%E4%BA%9B%E4%BA%8B%EF%BC%88%E4%B8%80%EF%BC%89.html  9  10 //KMP演算法;http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 11 //此方法主要利用了已經搜尋過的字串的位置資訊,利用被搜尋的字串的字元出現位置規律 12 //時間複雜度O(m+n) 13  14 void getNext(string p,int *next){ 15     int len=p.length(),i=0,k=-1; 16     if(len<=0) return; 17     next[i]=-1; 18      19     while(i<len-1){ 20         if(k==-1||p[i]==p[k]){//p[k]表示首碼,p[i]表示尾碼  21             k++; 22             i++; 23             if(p[i]!=p[k])  24                 next[i]=k;//若只有這一行,則會做很多無用功 25             else  26                 next[i]=next[k];//因為不能出現p[i] = p[ next[i ]],所以當出現時需要繼續遞迴,k = next[k] = next[next[k]]   27         } else { 28             k=next[k]; 29         } 30     } 31 } 32  33 int kmp_search(string s,string p,int *next){ 34     int sLen=s.length(),pLen=p.length(); 35     if(sLen<=0||pLen<=0) return -1; 36  37     int i=0,j=0; 38     while(i<sLen&&j<pLen){ 39         if(j==-1||s[i]==p[j]){ 40             i++; 41             j++; 42         } else if(s[i]!=p[j]) { 43             j=next[j]; 44         } 45     } 46     if(j==pLen) return i-j; 47     return -1; 48 } 49  50  51 //BM演算法 http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html 52 //http://www.cnblogs.com/a180285/archive/2011/12/15/BM_algorithm.html 53 //此方法從被搜尋字串的最後一個位置來比較字串,當失配時候,可以根據失配位置和被搜尋字串本身省去無效回溯。要比KMP演算法更快 54 //壞字元規則 好尾碼規則  55 //最好情況下的時間複雜度為O(n/m),最壞情況下時間複雜度為O(m·n)。n為母串長度,m是模式串長度 56  57 //建立壞字元規則,若壞字元沒有出現在模式串中,則直接將模式串移動到壞字元的下一個字元中 58 //若壞字元在模式串中,則把字串移動到第一個出現壞字元的位置與壞字元重合的位置 59 #define ASIZE 256 60 #define XSIZE 100 61 //壞字元規則 62 void preBmBc(char *x, int m, int bmBc[]) { 63     int i; 64     for (i = 0; i<ASIZE; ++i) 65         bmBc[i] = m; 66     for (i = m-2; i >=0; --i) 67         bmBc[x[i]] = m - i - 1; 68     } 69  70 //好尾碼規則,首碼和尾碼的最大公用串的長度 71 void suffixes(char* P, int m, int suffix[]){ 72     int i=0,q=0; 73     suffix[m-1]=m; 74     for (i=m-2;i>=0;--i){ 75         q=i; 76         while(q>=0&&P[q]==P[m-1-i+q]) 77             --q; 78         suffix[i]=i-q; 79     } 80 } 81 //計算完好尾碼之後,要計算bmGs[i] 表示遇到好尾碼時,模式串應該移動的距離, 82 //其中i表示好尾碼前面一個字元的位置(也就是壞字元的位置) 83 void preBmGs(char *x, int m, int bmGs[]) { 84     int i, j, suff[XSIZE]; 85     suffixes(x, m, suff); 86     for (i = 0; i < m; ++i) 87         bmGs[i] = m; 88     j = 0; 89     for (i = m - 1; i >= 0; --i) 90         if (suff[i] == i + 1) 91             for (; j < m - 1 - i; ++j)//模式串中沒有子串匹配上好尾碼,但找到一個最大首碼 92                 if (bmGs[j] == m) 93                     bmGs[j] = m - 1 - i; 94     for (i = 0; i <= m - 2; ++i)//模式串中有子串匹配上好尾碼 95         bmGs[m - 1 - suff[i]] = m - 1 - i; 96     } 97  98 void BM_search(char*T,char*P,int m,int bmGs[],int bmBc[]){ 99     int i=0,j = 0;100     while (j <= strlen(T) - strlen(P)) {101         for (i = strlen(P) - 1; i >= 0 && P[i] ==T[i + j]; --i){}102         if (i < 0){103             cout<<j<<endl;//找到匹配104             break;105         } else {106             j += max(bmGs[i], bmBc[T[i]]-(m-1-i));107         }108     }109 }110 111 int main(int argc,char**argv)112 {113     char* s="abcdababda", *p="ababda";114     115     /*int *next=(int*)malloc(p.length()*sizeof(int));116     getNext(p,next);117     int i=kmp_search(s,p,next);118     cout<<i<<endl;*/119 120     int bmBc[ASIZE],bmGs[XSIZE];121     preBmBc(p,strlen(p),bmBc);122     preBmGs(p,strlen(p),bmGs);123     BM_search(s,p,strlen(p),bmGs,bmBc);124 125     return 0;126 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.