bm算法

  1. /* 
  2.  
  3.   函数:void BuildBadCharacterShift(char *, int, int*) 
  4. 目的:根据好后缀规则做预处理,建立一张好后缀表 
  5. 参数:   
  6. pattern => 模式串P   
  7. plen => 模式串P长度      
  8. shift => 存放坏字符规则表,长度为的int数组       
  9. 返回:void            
  10. */  
  11. void BuildBadCharacterShift(char const* pattern, int plen, int* shift)  
  12. {  
  13.     forint i = 0; i < 256; i++ )     
  14.         *(shift+i) = plen;  
  15.     while ( plen >0 )          
  16.     {     
  17.         *(shift+(unsigned char)*pattern++) = --plen;          
  18.     }     
  19. }  
  1. /*! int search_badcharacter(char const*, int, char const*, int) 
  2.  
  3.   */bref 查找出模式串patn在主串src中第一次出现的位置  
  4.     
  5.     */return patn在src中出现的位置,当src中并没有patn时,返回-1  
  6.       
  7. */  
  8. int search_badcharacter(char const* src, int slen, char const* patn, int plen, int* shift)  
  9. {     
  10.     int s_idx = plen, p_idx;    
  11.     int skip_stride;      
  12.     if (plen == 0)        
  13.         return -1;  
  14.     while (s_idx <= slen)//计算字符串是否匹配到了尽头   
  15.     {     
  16.         p_idx = plen;     
  17.         while (src[--s_idx] == patn[--p_idx])//开始匹配       
  18.         {     
  19.             //if (s_idx < 0)   
  20.             //Return -1;      
  21.             if (p_idx == 0)       
  22.             {             
  23.                 return s_idx;         
  24.             }     
  25.         }  
  26.         skip_stride =  shift[(unsigned char)src[s_idx]];  
  27.         s_idx += (skip_stride>plen-p_idx ? skip_stride: plen-p_idx)+1;     
  28.     }     
  29.     return -1;    
  30. }  
  1. /* 
  2.   函数:void BuildGoodSuffixShift(char *, int, int*)  
  3. 目的:根据最好后缀规则做预处理,建立一张好后缀表     
  4. 参数: 
  5. pattern => 模式串P 
  6. plen => 模式串P长度 
  7. shift => 存放最好后缀表数组 
  8. 返回:void 
  9. */  
  10. void  BuildGoodSuffixShift(char const* pattern, int plen, int* shift)  
  11. {     
  12.     shift[plen-1] = 1;            // 右移动一位    
  13.     char end_val = pattern[plen-1];  
  14.     char const* p_prev, const* p_next, const* p_temp;  
  15.     char const* p_now = pattern + plen - 2;            // 当前配匹不相符字符,求其对应的shift  
  16.     bool isgoodsuffixfind = false;                    // 指示是否找到了最好后缀子串,修正shift值  
  17.     forint i = plen -2; i >=0; --i, --p_now)         
  18.     {     
  19.         p_temp = pattern + plen -1;   
  20.         isgoodsuffixfind = false;  
  21.         while ( true )        
  22.         {         
  23.             while (p_temp >= pattern && *p_temp-- != end_val);          // 从p_temp从右往左寻找和end_val相同的字符子串    
  24.             p_prev = p_temp;       // 指向与end_val相同的字符的前一个     
  25.             p_next = pattern + plen -2;             // 指向end_val的前一个  
  26.             // 开始向前匹配有以下三种情况      
  27.             //第一:p_prev已经指向pattern的前方,即没有找到可以满足条件的最好后缀子串  
  28.             //第二:向前匹配最好后缀子串的时候,p_next开始的子串先到达目的地p_now,   
  29.             //需要判断p_next与p_prev是否相等,如果相等,则继续住前找最好后缀子串     
  30.             //第三:向前匹配最好后缀子串的时候,p_prev开始的子串先到达端点pattern, 这个可以算是最好的子串  
  31.                     
  32.             if( p_prev < pattern  && *(p_temp+1) != end_val )         // 没有找到与end_val相同字符      
  33.                 break;  
  34.   
  35.             bool  match_flag = true;        //连续匹配失败标志    
  36.             while( p_prev >= pattern && p_next > p_now )        
  37.             {  
  38.                 if( *p_prev --!= *p_next-- )          
  39.                 {     
  40.                     match_flag = false;      //匹配失败   
  41.                     break;    
  42.                 }  
  43.             }  
  44.           
  45.             if( !match_flag )  
  46.                 continue;          //继续向前寻找最好后缀子串  
  47.             else      
  48.             {     
  49.                 //匹配没有问题, 是边界问题  
  50.                 if( p_prev < pattern || *p_prev != *p_next)    
  51.                 {  
  52.                     // 找到最好后缀子串  
  53.                     isgoodsuffixfind = true;  
  54.                     break;    
  55.                 }  
  56.                 // *p_prev == * p_next  则继续向前找    
  57.             }     
  58.         }  
  59.         shift[i] = plen - i + p_next - p_prev;  
  60.         if( isgoodsuffixfind )  
  61.             shift[i]--;               // 如果找到最好后缀码,则对齐,需减修正  
  62.     }  
  63. }  

 

  1. /*! int search_goodsuffix(char const*, int, char const*, int) 
  2.  
  3.   */bref 查找出模式串patn在主串src中第一次出现的位置  
  4.     
  5.     */return patn在src中出现的位置,当src中并没有patn时,返回-1  
  6.       
  7. */  
  8. int search_goodsuffix(char const* src, int slen, char const* patn, int plen, int* shift)  
  9. {  
  10.     int s_idx = plen, p_idx;    
  11.     int skip_stride;  
  12.     if (plen == 0)    
  13.         return -1;  
  14.       
  15.     while (s_idx <= slen)//计算字符串是否匹配到了尽头   
  16.     {     
  17.         p_idx = plen;  
  18.         while (src[--s_idx] == patn[--p_idx])//开始匹配   
  19.         {     
  20.             //if (s_idx < 0)   
  21.                 //return -1;  
  22.             if (p_idx == 0)   
  23.             {         
  24.                 return s_idx;     
  25.             }  
  26.         }  
  27.         skip_stride =  shift[p_idx];  
  28.         s_idx += skip_stride +1;  
  29.     }  
  30.     return -1;  
  31. }  

 

  1. /* 
  2. 函数:int* BMSearch(char *, int , char *, int, int *, int *) 
  3. 目的:判断文本串T中是否包含模式串P 
  4. 参数: 
  5. src => 文本串T 
  6. slen => 文本串T长度 
  7. ptrn => 模式串P 
  8. pLen => 模式串P长度 
  9. bad_shift => 坏字符表 
  10. good_shift => 最好后缀表 
  11. 返回: 
  12. int - 1表示匹配失败,否则反回                     
  13. */  
  14. int BMSearch(char const*src, int slen, char const*ptrn, int plen, int const*bad_shift, int const*good_shift)  
  15. {  
  16.     int s_idx = plen;    
  17.     if (plen == 0)    
  18.         return 1;  
  19.       
  20.     while (s_idx <= slen)//计算字符串是否匹配到了尽头   
  21.     {     
  22.         int p_idx = plen, bad_stride, good_stride;    
  23.         while (src[--s_idx] == ptrn[--p_idx])//开始匹配       
  24.         {         
  25.             //if (s_idx < 0)   
  26.                 //return -1;  
  27.               
  28.             if (p_idx == 0)       
  29.             {         
  30.                 return s_idx;     
  31.             }     
  32.         }  
  33.           
  34.         // 当匹配失败的时候,向前滑动  
  35.         bad_stride = bad_shift[(unsigned char)src[s_idx]];      //根据坏字符规则计算跳跃的距离  
  36.         good_stride = good_shift[p_idx];                                 //根据好后缀规则计算跳跃的距离  
  37.         s_idx += ((good_stride > bad_stride) ? good_stride : bad_stride )+1;//取大者      
  38.     }  
  39.     return -1;    
  40. }  
posted @ 2013-05-30 15:21  麦峰强  阅读(460)  评论(0编辑  收藏  举报