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

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

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;
}

实践中更高效、实现起来相对简单的基于末尾坏字符原则的BM算法实现的更多相关文章

  1. unittest中更高效的执行测试用例一个类只需要打开一次浏览器

    示例代码 baidu.py # _*_ coding:utf-8 _*_ import csv,unittest #导入csv模块 from time import sleep from seleni ...

  2. 微服务平台(Micro Service Platform : MSP)旨在提供一个集开发、测试、运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效。

    微服务平台(Micro Service Platform : MSP)旨在提供一个集开发.测试.运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效. MSP采用业界 ...

  3. 使jQuqer更高效的方法

    讨论 jQuery 和 javascript 性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的 jQuery 和 javascript 代码.好的代码会带来速度 ...

  4. 在Dubbo中使用高效的Java序列化(Kryo和FST)

    在Dubbo中使用高效的Java序列化(Kryo和FST) 作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… TODO 生成可点击的目录 目录 序列化漫 ...

  5. 阿里巴巴 Kubernetes 应用管理实践中的经验与教训

    作者 | 孙健波(阿里巴巴技术专家).赵钰莹 导读:云原生时代,Kubernetes 的重要性日益凸显.然而,大多数互联网公司在 Kubernetes 上的探索并非想象中顺利,Kubernetes 自 ...

  6. 从 DevOps 到 Serverless:通过“不用做”的方式解决“如何更高效做”的问题

    作者 | 徐进茂(罗离) JAVA 开发工程师  导读:近年来,Serverless 一词越来越热,它已经逐渐成为了一种新型的软件设计架构.和 DevOps 概念提倡的是通过一系列工具和自动化的技术来 ...

  7. 更强、更稳、更高效:解读 etcd 技术升级的三驾马车

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 陈星宇(宇慕 ...

  8. 用好Java中的枚举真的没有那么简单

    1.概览 在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式. enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承j ...

  9. K8s 如何提供更高效稳定的编排能力?K8s Watch 实现机制浅析

    关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...

随机推荐

  1. Android 5.0 + IDA 6.8 调试经验分享

    如今升级快.网上的资料仅仅能做參考. 学到了NDK逆向这一块,昨天为了能让IDA 能动态调试SO,瞎折腾了非常久,这里分享一下我的经验. 工具: IDA pro 6.8 Android 5.x IDA ...

  2. JS操作frame框架

    1 框架编程概述 一个Html 页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一 个独立的Html 页面.这里所讲的框架编程包括框架的自我控制以及框架之间的互相访 ...

  3. IntelliJ IDEA java项目导入jar包,打jar包

    一.导入 1.java项目在没有导入该jar包之前,如图: 2.点击 File ->  Project Structure(快捷键 Ctrl + Alt + Shift + s),点击Proje ...

  4. HDUOJ---1241Oil Deposits(dfs)

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  5. windows批处理文件打印幻方

    无论是批处理文件还是shell都是没有意义的,它们只是一种工具,并且是非常低级难懂的工具. 如果不会,那就保持不会就好了.不要花费太多时间在这些没意义的事情上. 批处理的没意义体现在: 难以表达 随便 ...

  6. QRCode - 二维码识别与生成

    来源:Yi'mouleng(@丶伊眸冷) 链接:http://t.cn/R40WxcM 前言 有关二维码的介绍,我这里不做过多说明, 可以直接去基维百科查看,附上链接QR code(https://e ...

  7. 跳出框架iframe的操作语句

    常用的iframe操作语句 ①   本页面跳转语句: "window.location.href" 或者 "location.href" ②   上一层页面跳转 ...

  8. python练习笔记——map | sum | pow 的应用

    1 函数简要 map 函数  | sum 函数  |  pow函数  | lambda函数 2 简要计算 2.1 1^2 + 2^2 + 3^2 .....9^2 方法1 print([pow(x,2 ...

  9. Python学习笔记012——装饰器

    1 装饰器 1.1装饰器定义 在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 1.2 装饰器分类 装饰器:函数装饰器,类装饰器,函数的装饰器,类的装饰器 装饰器:函数装饰函 ...

  10. RHCE7 -- systemctl命令

    查询所有单元的状态: [root@rhce7 ~]# systemctl UNIT LOAD ACTIVE SUB DESCRIPTION proc-sys-fs-binfmt_misc.automo ...