KMP演算法學習

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   ar   strong   for   

一、什麼是KMP演算法

Knuth-Morris-Pratt 字串尋找演算法(常簡稱為 “KMP演算法”)是在一個“主文本字串” S 內尋找一個“詞” W 的出現,,以此避免對以前匹配過的字元重新檢查。(在原串中匹配模式串)


二、KMP示範


http://staff.ustc.edu.cn/~ypb/jpkc/flash/Find_KMP.swf


三、KMP原理

KMP是一種最常見的改進演算法,它可以在匹配過程中失配的情況下,有效地多往後面跳幾個字元,加快匹配速度。


在KMP演算法中有個數組,叫做首碼數組,也有的叫,每一個模式串都有一個固定的next數組,,當然它描述的也是子串的對稱程度,程度越高,值越大,當然之前可能出現再匹配的機會就更大。


對於next數組的理解,參見http://blog.csdn.net/yearn520/article/details/6729426#t0




 

[cpp] view plaincopy
  1. void SetPrefix(const char *Pattern, int prefix[])  
  2. {  
  3.      int i;  
  4.      int len=strlen(Pattern);//模式字串長度。  
  5.      prefix[0]=0;  
  6.      for(i=1; i<len; i++)  
  7.      {  
  8.          int k=prefix[i-1];  
  9.          //不斷遞迴判斷是否存在子對稱,k=0說明不再有子對稱,Pattern[i] != Pattern[k]說明雖然對稱,但是對稱後面的值和當前的字元值不相等,所以繼續遞推  
  10.          while( Pattern[i] != Pattern[k] && k!=0 )//例i等於14時,求prefix[14]的值  
  11.              k=prefix[k-1]; //繼續遞迴  
  12.          if( Pattern[i] == Pattern[k])//找到了這個子對稱,或者是直接繼承了前面的對稱性,這兩種都在前面的基礎上++  
  13.               prefix[i]=k+1;  
  14.          else  
  15.               prefix[i]=0; //如果遍曆了所有子對稱都無效,說明這個新字元不具有對稱性,清0  
  16.      }  
  17.   prefix[0]=-1;  
  18. }  

四、測試小例[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <cstring>  
  3. #include <string>  
  4. using namespace std;  
  5.   
  6. string sorg;  
  7. string spat;  
  8. int prefix[10000];  
  9. int result[20];  
  10.   
  11. void init()  
  12. {  
  13.     sorg="";  
  14.     spat="";  
  15.     memset(prefix,0,sizeof(int)*10000);  
  16.     //memset(result,0,sizeof(int)*20);  
  17. }  
  18. void setprefix(string temp,int next[])  
  19. {  
  20.     int len=temp.size();  
  21.     next[0]=0;  
  22.   
  23.     for(int i=1;i<len;i++)  
  24.     {  
  25.         int k=next[i-1];  
  26.   
  27.         while(temp[k]!=temp[i]&&k!=0)  
  28.             k=next[k-1];  
  29.   
  30.         if(temp[k]==temp[i])  
  31.             next[i]=k+1;  
  32.         else  
  33.             next[i]=0;  
  34.     }  
  35.   
  36.     next[0]=-1;  
  37.   
  38.     for(int i=0;i<len;i++)  
  39.         if(next[i]>=1)  
  40.             next[i]=next[i]-1;  
  41. }  
  42.   
  43. int  kmp(string s1,string s2)  
  44. {  
  45.     int number=0;  
  46.     int i=0;  
  47.     int j=0;  
  48.     while(i<(int)s1.size()&&j<(int)s2.size())  
  49.     {  
  50.         if(j==-1||s1[i]==s2[j])  
  51.         {  
  52.             i++;  
  53.             j++;  
  54.         }  
  55.         else  
  56.             j=prefix[j];  
  57.   
  58.         if(j==s2.size())  
  59.         {  
  60.             i=i-j+1;  
  61.             j=0;  
  62.             number++;  
  63.         }  
  64.     }  
  65.   
  66.     return number;  
  67. }  
  68. int main()  
  69. {  
  70.     int t;  
  71.     cin>>t;  
  72.     memset(result,0,sizeof(int)*20);  
  73.     for(int i=0;i<t;i++)  
  74.     {  
  75.         init();  
  76.         //cout<<"input spat string:"<<endl;  
  77.         cin>>spat;  
  78.   
  79.         //cout<<"input sorg string:"<<endl;  
  80.         cin>>sorg;  
  81.   
  82.         setprefix(spat,prefix);  
  83.         result[i]=kmp(sorg,spat);  
  84.     }  
  85.   
  86.     for(int j=0;j<t;j++)  
  87.         cout<<result[j]<<endl;  
  88.   
  89.   
  90.     return 0;  
  91. }  




KMP演算法學習

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.