实践中更高效、实现起来相对简单的基于末尾坏字符原则的BM算法实现
之前网上看的若干算法,无非两个原则:坏字符原则、好后缀原则。按照算法所述实现了一个版本,但发现其效率还不如本文所述的实现方式。个人分析效率较低的原因可能是因为不断地向前找坏字符或者好后缀来确定跳跃距离导致的,不断的比对操作应该是影响效率的根源。
下面贴一段实现较简单的方法,感谢之前的领导磊哥,实现参照了他的代码。
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算法实现的更多相关文章
- unittest中更高效的执行测试用例一个类只需要打开一次浏览器
示例代码 baidu.py # _*_ coding:utf-8 _*_ import csv,unittest #导入csv模块 from time import sleep from seleni ...
- 微服务平台(Micro Service Platform : MSP)旨在提供一个集开发、测试、运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效。
微服务平台(Micro Service Platform : MSP)旨在提供一个集开发.测试.运维于一体的开发者专属平台,让开发者能快速构建或使用微服务,让开发更简单,让运维更高效. MSP采用业界 ...
- 使jQuqer更高效的方法
讨论 jQuery 和 javascript 性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的 jQuery 和 javascript 代码.好的代码会带来速度 ...
- 在Dubbo中使用高效的Java序列化(Kryo和FST)
在Dubbo中使用高效的Java序列化(Kryo和FST) 作者:沈理 文档版权:Creative Commons 3.0许可证 署名-禁止演绎 完善中…… TODO 生成可点击的目录 目录 序列化漫 ...
- 阿里巴巴 Kubernetes 应用管理实践中的经验与教训
作者 | 孙健波(阿里巴巴技术专家).赵钰莹 导读:云原生时代,Kubernetes 的重要性日益凸显.然而,大多数互联网公司在 Kubernetes 上的探索并非想象中顺利,Kubernetes 自 ...
- 从 DevOps 到 Serverless:通过“不用做”的方式解决“如何更高效做”的问题
作者 | 徐进茂(罗离) JAVA 开发工程师 导读:近年来,Serverless 一词越来越热,它已经逐渐成为了一种新型的软件设计架构.和 DevOps 概念提倡的是通过一系列工具和自动化的技术来 ...
- 更强、更稳、更高效:解读 etcd 技术升级的三驾马车
点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 陈星宇(宇慕 ...
- 用好Java中的枚举真的没有那么简单
1.概览 在本文中,我们将看到什么是 Java 枚举,它们解决了哪些问题以及如何在实践中使用 Java 枚举实现一些设计模式. enum关键字在 java5 中引入,表示一种特殊类型的类,其总是继承j ...
- K8s 如何提供更高效稳定的编排能力?K8s Watch 实现机制浅析
关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...
随机推荐
- 让 linux centos 文件夹地址栏 位置栏显示出来的方法
今天又拿起心爱的 linux ,发现多日不用又忘记了不少知识了 , 发现忘记的速度真是惊人的! 设置方法: 编辑-> 首选项-> 勾选 总是在浏览器窗口中打开, 如图:
- Exception in thread main java.lang.NoClassDefFoundError: org/apache/juli/logging/LogFacto
报错: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/juli/logging/Log ...
- Foundations of Machine Learning: The PAC Learning Framework(2)
Foundations of Machine Learning: The PAC Learning Framework(2) (一)假设集有限在一致性下的学习界. 在上一篇文章中我们介绍了PAC-le ...
- 【LeetCode】12. Integer to Roman (2 solutions)
Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be within t ...
- 避免全表扫描的sql优化
对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引: .尝试下面的技巧以避免优化器错选了表扫描: · 使用ANALYZE TABLE tbl_na ...
- hello oc
printf("Hello C\n"); //OC可以采用C语言的输出方式 printf("The number is %d\n",100);//%d 输出数字 ...
- Mosquitto ---学习笔记
Mosquitto的安装,可以参见:https://mosquitto.org/download/ [基础配置]Mosquitto服务的配置文件为/etc/mosquitto/mosquitto.co ...
- go 学习 ---package
1.包简述 GO本身没有项目的概念,只有包,包括可执行包和不可执行包,而不管什么包,都应该包含在 $GOPATH/src 目录下,GO命令和编译器会在 $GOPATH/src 目录下搜索相应的包.比如 ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- Linux内核中锁机制之原子操作、自旋锁
很多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实是由于操作系统中存在多进程对共享资源的并发访问,从而引起了进程间的竞态.这其中包括了我们所熟知的SMP系统,多 ...