之前网上看的若干算法,无非两个原则:坏字符原则、好后缀原则。按照算法所述实现了一个版本,但发现其效率还不如本文所述的实现方式。个人分析效率较低的原因可能是因为不断地向前找坏字符或者好后缀来确定跳跃距离导致的,不断的比对操作应该是影响效率的根源。

下面贴一段实现较简单的方法,感谢之前的领导磊哥,实现参照了他的代码。

PS:大概看了下ClamAV的BM实现,感觉很复杂。

 #define BM_TAB_LEN  (256)

 uint64_t *InitBMTab(const uint8_t *In_ui8Pattern, uint64_t In_ui64PattLen)
{
uint64_t *pui64RetVal = NULL; if (In_ui8Pattern == NULL || In_ui64PattLen == )
{
goto fun_ret;
} pui64RetVal = (uint64_t *)malloc(sizeof(uint64_t) * BM_TAB_LEN);
if (pui64RetVal == NULL)
{
goto fun_ret;
} for (uint16_t i = ; i < BM_TAB_LEN; i ++)
{
pui64RetVal[i] = In_ui64PattLen;
} for (uint64_t i = ; i < In_ui64PattLen; i ++)
{
pui64RetVal[In_ui8Pattern[i]] = In_ui64PattLen - i - ;
} fun_ret:
return pui64RetVal;
} int8_t ReBuildBMTab(uint64_t *Out_pui64BMJmpTab, const uint8_t *In_ui8Pattern, uint64_t In_ui64PattLen)
{
int8_t i8RetVal = ; if (Out_pui64BMJmpTab == NULL || In_ui8Pattern == NULL || In_ui64PattLen == )
{
i8RetVal = -;
goto fun_ret;
} for (uint16_t i = ; i < BM_TAB_LEN; i ++)
{
Out_pui64BMJmpTab[i] = In_ui64PattLen;
} for (uint64_t i = ; i < In_ui64PattLen; i ++)
{
Out_pui64BMJmpTab[In_ui8Pattern[i]] = In_ui64PattLen - i - ;
} fun_ret:
return i8RetVal;
} void ReleaseBMTab(uint64_t *Out_pui64BMJmpTab)
{
if (Out_pui64BMJmpTab != NULL)
{
free(Out_pui64BMJmpTab);
}
} uint64_t BMSearch(const uint64_t *In_pui64BMJmpTab, const uint8_t *In_pui8Pattern, uint64_t In_ui64PattLen,
const uint8_t *In_pui8Buf, uint64_t In_ui64BufLen)
{
uint64_t ui64RetVal = -;
uint64_t ui64EndIdx = ; if (In_pui64BMJmpTab == NULL || In_pui8Pattern == NULL
|| In_ui64PattLen == || In_pui8Buf == NULL || In_ui64BufLen ==
|| In_ui64BufLen < In_ui64PattLen)
{
goto fun_ret;
} ui64EndIdx = In_ui64PattLen - ;
do
{
if (In_pui64BMJmpTab[In_pui8Buf[ui64EndIdx]] != )
{
ui64EndIdx += In_pui64BMJmpTab[In_pui8Buf[ui64EndIdx]];
continue;
}
if (memcmp(In_pui8Pattern, In_pui8Buf + ui64EndIdx - In_ui64PattLen + , In_ui64PattLen) == )
{
ui64RetVal = ui64EndIdx - In_ui64PattLen + ;
goto fun_ret;
}
ui64EndIdx ++;
} while (ui64EndIdx < In_ui64BufLen); fun_ret:
return ui64RetVal;
}

最新文章

  1. [LeetCode] Meeting Rooms II 会议室之二
  2. MVC与MVVM区别?
  3. CentOS 程序开机自启动方法总结
  4. 深入理解jQuery中的Deferred
  5. poj 3349:Snowflake Snow Snowflakes(哈希查找,求和取余法+拉链法)
  6. [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
  7. 【iCore3 双核心板】例程五:SYSTICK定时器实验——定时点亮LED
  8. Xshell快捷键
  9. Winform开发的界面处理优化
  10. common.js
  11. 安装Ubuntu时,遇到自定义交换空间swap大小设置问题
  12. linux驱动系列之s3c2440内存布局
  13. 【原创】Matlab中plot函数全功能解析
  14. 如何完全禁用或卸载Windows 10中的OneDrive - 51CTO.COM
  15. Ionic 2+ 安卓环境搭建
  16. Go 到底有没有引用传参(对比 C++ )
  17. 在Altium Designer 10中实现元器件旋转45&#176;角放置
  18. Echarts柱状图的点击事件
  19. geoserver 启动闪退
  20. iOS开发debug跟release版本NSLog屏蔽方法

热门文章

  1. HDUOJ---The Moving Points
  2. 马老师 linux必备web服务入门及高级进阶
  3. Extending_and_embedding_php翻译
  4. ubuntu 忘记root密码了不用怕,看这里
  5. 转 生成 HTMLTestRunner 测试报告
  6. 如何不让DataGridView自动生成列
  7. android自动弹出软键盘(输入键盘)
  8. Linux调度器 - deadline调度器
  9. C++防止头文件反复包括
  10. Android设计中的.9.png图片