字符串匹配之Shift And算法

来源:互联网 发布:jdbc示例数据库 编辑:程序博客网 时间:2024/05/29 14:36
基于前缀的搜索——详情参阅《柔性字符串匹配》这本好书,别的就不多说了

直接给出我的实现...
  1. template <class Output_Function>
  2. size_t Shift_And(const char* source,const char* to_find,Output_Function out){
  3. /**
  4.  * 在source中查找to_find,利用out输出每次出现的地方
  5.  * 返回to_find在source中出现的次数
  6.  */
  7.     size_t n=strlen(source),m=strlen(to_find);
  8.     size_t occured=0;
  9.     if (n<m) return 0;
  10.     const int mask_len=m/64+1;
  11.     const int last_section_len=m%64;
  12.     __int64 mask[128][mask_len]; //GCC support VLA well, Why not use it ?
  13.     for(int i=0;i<mask_len;++i){
  14.         for(int j=0;j<128;++j){
  15.             mask[j][i]=0;
  16.         }
  17.     }
  18.     for(size_t j=0;j<m;++j){
  19.         mask[static_cast<int>(to_find[j])][j/64]|=1<<(j%64);
  20.     }
  21.     __int64 D[mask_len];
  22.     for(int i=0;i<mask_len;++i){
  23.         D[i]=0;
  24.     }
  25.     for(size_t pos=0;pos<n;++pos){
  26.         for(int i=mask_len-1;i>=1;--i){
  27.             D[i]<<=1;
  28.             D[i]|=D[i-1]>>63;
  29.             D[i]&=mask[static_cast<int>(to_find[pos])][i];
  30.         }
  31.         D[0]<<=1;
  32.         D[0]|=1;
  33.         D[0]&=mask[static_cast<int>(source[pos])][0];
  34.         if (D[mask_len-1]>>(last_section_len-1)){
  35.             out(pos-m+1);
  36.             ++occured;
  37.         }
  38.     }
  39.     return occured;
  40. }