Go语言实现bitmap算法
有关bitmap算法的介绍资料网上很多,这里不赘述,各种语言的实现也不少,但是Go语言版的bitmap不多,本文就来写一个Go版的bitmap实现。
首先创建一个 bitmap.go 文件,定义一个bitmap结构体,再提供一些操作方法。详细代码如下:
package bitmap import (
"fmt"
"strings"
) const (
bitSize = 8
) var bitmask = []byte{1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7}
// 首字母小写 只能调用 工厂函数 创建
type bitmap struct {
bits []byte
bitCount uint64 // 已填入数字的数量
capacity uint64 // 容量
}
// 创建工厂函数
func NewBitmap(maxnum uint64) *bitmap {
return &bitmap{bits: make([]byte, (maxnum+7)/bitSize), bitCount: 0, capacity: maxnum}
} // 填入数字
func (this *bitmap) Set(num uint64) {
byteIndex, bitPos := this.offset(num)
// 1 左移 bitPos 位 进行 按位或 (置为 1)
this.bits[byteIndex] |= bitmask[bitPos]
this.bitCount++
} // 清除填入的数字
func (this *bitmap) Reset(num uint64) {
byteIndex, bitPos := this.offset(num)
// 重置为空位 (重置为 0)
this.bits[byteIndex] &= ^bitmask[bitPos]
this.bitCount--
} // 数字是否在位图中
func (this *bitmap) Test(num uint64) bool {
byteIndex := num / bitSize
if byteIndex >= uint64(len(this.bits)) {
return false
}
bitPos := num % bitSize
// 右移 bitPos 位 和 1 进行 按位与
return !(this.bits[byteIndex]&bitmask[bitPos] == 0)
} func (this *bitmap) offset(num uint64) (byteIndex uint64, bitPos byte) {
byteIndex = num / bitSize // 字节索引
if byteIndex >= uint64(len(this.bits)) {
panic(fmt.Sprintf(" runtime error: index value %d out of range", byteIndex))
return
}
bitPos = byte(num % bitSize) // bit位置
return byteIndex, bitPos
} // 位图的容量
func (this *bitmap) Size() uint64 {
return uint64(len(this.bits) * bitSize)
} // 是否空位图
func (this *bitmap) IsEmpty() bool {
return this.bitCount == 0
} // 是否已填满
func (this *bitmap) IsFully() bool {
return this.bitCount == this.capacity
} // 已填入的数字个数
func (this *bitmap) Count() uint64 {
return this.bitCount
} // 获取填入的数字切片
func (this *bitmap) GetData() []uint64 {
var data []uint64
count := this.Size()
for index := uint64(0); index < count; index++ {
if this.Test(index) {
data = append(data, index)
}
}
return data
} func (this *bitmap) String() string {
var sb strings.Builder
for index := len(this.bits) - 1; index >= 0; index-- {
sb.WriteString(byteToBinaryString(this.bits[index]))
sb.WriteString(" ")
}
return sb.String()
} func byteToBinaryString(data byte) string {
var sb strings.Builder
for index := 0; index < bitSize; index++ {
if (bitmask[7-index] & data) == 0 {
sb.WriteString("0")
} else {
sb.WriteString("1")
}
}
return sb.String()
}
代码中有注释,很容易看懂。下面写测试代码,测试这个bitmap。
package main import (
"bitmap"
"fmt"
) func main() {
array := [...]uint64{0, 6, 3, 7, 2, 8, 1, 4} var maxNum uint64 = 9
bm := bitmap.NewBitmap(maxNum) for _, v := range array {
bm.Set(v)
}
bm.Set(5)
fmt.Println(bm.IsFully())
fmt.Println(bm.IsEmpty())
fmt.Println("bitmap 中存在的数字:")
fmt.Println(bm.GetData())
fmt.Println("bitmap 中的二进制串")
fmt.Println(bm.String())
fmt.Println("bitmap 中的数字个数:", bm.Count())
fmt.Println("bitmap size:", bm.Size())
fmt.Println("Test(0):", bm.Test(0))
bm.Reset(5)
fmt.Println(bm.String())
fmt.Println("Test(5):", bm.Test(5))
fmt.Println(bm.GetData())
}
测试代码的输出如下:
true
false
bitmap 中存在的数字:
[0 1 2 3 4 5 6 7 8]
bitmap 中的二进制串
00000001 11111111
bitmap 中的数字个数: 9
bitmap size: 16
Test(0): true
00000001 11011111
Test(5): false
[0 1 2 3 4 6 7 8]
最后小结,bitmap的实现代码可以根据需要添加其它方法,本文的实现仅供参考。另外文中的代码不是线程安全的,多线程中使用需要改写bitmap的代码加上锁。
Go语言实现bitmap算法的更多相关文章
- bitmap算法
概述 所谓bitmap就是用一个bit位来标记某个元素对应的value,而key即是这个元素.由于采用bit为单位来存储数据,因此在可以大大的节省存储空间 算法思想 32位机器上,一个整形,比如int ...
- BitMap 算法
什么是 BigMap 算法 所谓 BitMap 就是用一个 bit 位来标记某个元素对应的 value,而 key 即是这个元素.由于采用bit为单位来存储数据,因此在可以大大的节省存储空间. 算法思 ...
- BitMap算法及其实现(Python)
BitMap概述 本文介绍 BitMap 算法的应用背景,算法思想和相关实现细节. 概括而言,BitMap 主要用来解决海量数据中元素查询,去重.以及排序等问题.这里对海量数据场景的强调,似乎暗示了这 ...
- BitMap算法应用:Redis队列滤重优化
工作中有用到Redis滤重队列. 原来的方法如下: 方法一 为了保证操作原子性,使用Redis执行Lua脚本. 在脚本中的逻辑是,如果队列不超过某个数值,进行一次lrem操作(队列使用list结构), ...
- 10个经典的C语言面试基础算法及代码
10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...
- 数据结构C语言版 弗洛伊德算法实现
/* 数据结构C语言版 弗洛伊德算法 P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...
- 经典算法题每日演练——第十一题 Bitmap算法
原文:经典算法题每日演练--第十一题 Bitmap算法 在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美, 但是在特定的场 ...
- 【算法与数据结构专场】BitMap算法基本操作代码实现
上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...
- 浅谈bitmap算法
一.bitmap算法思想 32位机器上,一个整形,比如int a; 在内存中占32bit位,可以用对应的32bit位对应十进制的0-31个数,bitmap算法利用这种思想处理大量数据的排序与查询. ...
随机推荐
- 组件化网页开发 / 步骤二 · 2-11 jquery的ajax方法 以及下一章跨域没懂
1,根据2-11课程老师的提示,自己封装 $.ajax 2,第三章,跨域,没看懂
- JQuery 实践--让页面动起来
获取和设置元素特性特性属性:是指DOM元素中能够和HTML元素中某个特性对应得上的属性.通常JS特性属性的名称与对应的特性一一匹配,但class <=>className操作特性还是操作属 ...
- 【安卓基础】使用Guideline与约束辅助布局的平分空间设计
ConstraintLayout布局已经推出了很长一段时间,功能也是比较强大,能有效减少界面的视图层级嵌套,一定程度提升界面绘制效率. 在项目中,我也是最近才选择开始使用ConstraintLayou ...
- 菜鸟 Python 100例
以下参考:菜鸟教程 python100例 == 推荐博客 有四个数字: 1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? import itertools a = ('1','2' ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths (dsu on tree) 题解
先说一下dsu算法. 例题:子树众数问题. 给出一棵树,每个点有点权,求每个子树中出现次数最多的数的出现次数. 树的节点数为n,\(n \leq 500000\) 这个数据范围,\(O(n \sqrt ...
- LNOI2018 劈配
主要思路为连反向边. 对于本题,贪心策略,依次决定每个人的最优解 但因为每人达到的最优解可能有多种方式,如果每个都尝试就会超时,所以只能先采取其中一种 并将这个方案连反向边,其它方案连正向边 这样对于 ...
- jQuery.merge(first,second)
jQuery.merge(first,second) 概述 合并两个数组 返回的结果会修改第一个数组的内容——第一个数组的元素后面跟着第二个数组的元素.要去除重复项,请使用$.unique() 参数 ...
- slf4j、jcl、jul、log4j1、log4j2、logback大总结[转]
#1 系列目录 jdk-logging.log4j.logback日志介绍及原理 commons-logging与jdk-logging.log4j1.log4j2.logback的集成原理 slf4 ...
- tomcat控制前台到后台的乱码问题
1.找到tomcat中的conf文件下的server.xml文件. 2.点击打开后找到 <Connector port="8080" protocol="HTTP ...
- 【转】CAtlRegExp class .
CAtlRegExp Class CAtlRegExp 类用于表示并处理正则表达式.模板类,定义如下: template < class CharTraits = CAtlRECha ...