实践中更高效、实现起来相对简单的基于末尾坏字符原则的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 实现机制浅析
关于我们 更多关于云原生的案例和知识,可关注同名[腾讯云原生]公众号~ 福利: ①公众号后台回复[手册],可获得<腾讯云原生路线图手册>&<腾讯云原生最佳实践>~ ②公 ...
随机推荐
- 更改npm全局模块和cache默认安装位置
来源于:http://blog.csdn.net/friendan/article/details/51736231 1.因为我安装的Node.js自带了npm,所以在nodejs文件夹里面新建以下两 ...
- Spring +Mybatis 企业应用实战(脑图)
- HDUOJ-----1541 Stars
Stars Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- C#基础 - C# 的 常见概念简述
在上篇文章中,你跟着我写了一个HelloWorld,本篇中,我们来谈谈一些C#程序中的小概念 1.C# 程序结构 一个 C# 程序主要包括以下部分: 命名空间声明(Namespace declarat ...
- JMeter学习笔记--详解JMeter配置元件
JMeter配置元件可以用来初始化默认值和变量,以便后续采样器使用.将在其作用域的初始化阶段处理. CSV Data Set Config:被用来从文件中读取数据,并将它们拆分后存储到变量中,适合处理 ...
- Unix环境高级编程(八)进程关系
本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用.通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态.先将本章基本的知识点总结如下,日后再看时候 ...
- Web - TCP与UDP的差别
是否面向连接:TCP面向连接.UDP面向非连接. 传输可靠性:TCP可靠.UDP不可靠. 应用场合:TCP经常使用于传输大量数据,UDP经常使用于传输少量数据. 速度:TCP传输速度较慢,而UDP速度 ...
- CodeForces 550A Two Substrings(模拟)
[题目链接]click here~~ [题目大意]: You are given string s. Your task is to determine if the given string s ...
- Python floor() 函数
描述 floor(x) 函数返回一个小于或等于 x 的的最大整数(向下取整) 语法 以下是 floor() 方法的语法: import math math.floor( x ) 注意:floor()是 ...
- yii2 数据库操作详解(转载)
开始使用数据库首先需要配置数据库连接组件,通过添加 db 组件到应用配置实现("基础的" Web 应用是 config/web.php),DSN( Data Source Name ...