基于前缀的搜索——详情参阅《柔性字符串匹配》这本好书,别的就不多说了
直接给出我的实现...
- template <class Output_Function>
- size_t Shift_And(const char* source,const char* to_find,Output_Function out){
- /**
- * 在source中查找to_find,利用out输出每次出现的地方
- * 返回to_find在source中出现的次数
- */
- size_t n=strlen(source),m=strlen(to_find);
- size_t occured=0;
- if (n<m) return 0;
- const int mask_len=m/64+1;
- const int last_section_len=m%64;
- __int64 mask[128][mask_len]; //GCC support VLA well, Why not use it ?
- for(int i=0;i<mask_len;++i){
- for(int j=0;j<128;++j){
- mask[j][i]=0;
- }
- }
- for(size_t j=0;j<m;++j){
- mask[static_cast<int>(to_find[j])][j/64]|=1<<(j%64);
- }
- __int64 D[mask_len];
- for(int i=0;i<mask_len;++i){
- D[i]=0;
- }
- for(size_t pos=0;pos<n;++pos){
- for(int i=mask_len-1;i>=1;--i){
- D[i]<<=1;
- D[i]|=D[i-1]>>63;
- D[i]&=mask[static_cast<int>(to_find[pos])][i];
- }
- D[0]<<=1;
- D[0]|=1;
- D[0]&=mask[static_cast<int>(source[pos])][0];
- if (D[mask_len-1]>>(last_section_len-1)){
- out(pos-m+1);
- ++occured;
- }
- }
- return occured;
- }