串的模式匹配算法---RK


這一節介紹一下由Rabin和Karp提出的RK算法。

1,RK算法的基本思想

     HASH!

     如果兩個字符串hash后的值不相同,則它們肯定不相同;如果它們hash后的值相同,它們不一定相同。

     RK算法的基本思想就是:將模式串P的hash值跟主串S中的每一個長度為|P|的子串的hash值比較。如果不同,則它們肯定不相等;如果相同,則再諸位比較之。

2,RK算法的求解過程

    將我們用來比較的字符串的全集設為∑={a,b,…,z},設∑的長度為d=|∑|,則主串和模式串都可以看作是d進制數。例如只由數字組成的字符串,它的全集∑={0,1,2,3,4,5,6,7,8,9},d=10。

    設模式串為P,其長度為m,主串為S,其長度為n。則模式串P可以看作是一個m位的d進制數A,主串S可以看作是一個n位的d進制數。我們的模式匹配過程就是將A與主串中的每個長度為m的d進制數S[t…t+m-1] (t=0,1,2,…,n-m+1)的值做比較,所以整個模式匹配過程就變成了兩個d進制數之間的比較過程。例如模式串為123,主串為65127451234,就是將十進制數123跟十進制數651, 512, 127, 274, 745, 451, 512, 123的逐個比較過程。

    明確了匹配過程,下面就是求解A和求解S[t…t+m-1] (t=0,1,2,…,n-m+1)的過程:

       1)求解A。根據多項式計算方法,A = P[m-1] + d * (P[m-2] + d * (P[m-3] + …+ d * (P[1] + d*P[0])…))

       2)求解S[t…t+m-1]。為了方便表示,我們設S[t…t+m-1] = St,則S[t+1…t+m] = St+1

              假設已求得St,現在要求St+1,需要注意的是St+1是St去掉高位數據,其余的m-1位乘以d后再在最低位加一位得到。於是

                                            St+1 = d * (St – dm-1*S[t]) + S[t+m]

     公式比較晦澀,舉個例子看看吧。比如上面例子中主串是65127451234。S2=127,那么S3=10×(127-102×1)+ 4 = 274

   

     現在的問題是,如果A的值太大,比較的過程會比較耗時,這個時候我們可以將這個大數mod q(q是一個大素數),同理,st也mod q,將兩個取模之后的數相比較。

 

3,RK算法的實現    

 1 #define q 144451
 2 #define d 26
 3 
 4 int isMatch(char *S, int i, char *P, int m)  5 {  6     int is, ip;  7     for(is=i, ip=0; is != m && ip != m; is++, ip++)  8         if(S[is] != P[ip])  9             return 0; 10     return 1; 11 } 12 
13 /*
14  * 字符串匹配的RK算法 15  * Author:Rabin & Karp 16  * 實現:CobbLiu 17  * 若成功匹配返回主串中的偏移,否則返回-1 18  */
19 int RK(char *S, char *P) 20 { 21     int m  = strlen(P); 22     int n  = strlen(S); 23     unsigned int h   = 1
24     unsigned int A   = 0; 25     unsigned int St  = 0; 26     int i; 27 
28     //初始化,算出最d進制下的最高位
29     for(i = 0;i < m - 1;i++) 30         h = (h*d) % q; 31 
32     for(i = 0; i != m; i++){ 33         A = (d*A + (P[i] - 'a')) % q; 34         St = (d*St + (S[i] - 'a')) % q; 35  } 36 
37     for(i = 0; i != n-m; i++){ 38         if(A == St) 39             if(isMatch(S,i,P,m)) 40                 return i; 41         St = (d*(St - h*(S[i]-'a'))+(S[i+m]-'a')) % q; 42  } 43 
44     return -1; 45 }

 

4,算法的復雜度分析

  如果選擇的素數q>=m, 則RK算法的期望運行時間為O(n+m), 如果m<<n,則算法的期望運行時間為O(n)。具體推理過程請參看《算法導論》第32章P562頁。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM