有关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算法的更多相关文章

  1. bitmap算法

    概述 所谓bitmap就是用一个bit位来标记某个元素对应的value,而key即是这个元素.由于采用bit为单位来存储数据,因此在可以大大的节省存储空间 算法思想 32位机器上,一个整形,比如int ...

  2. BitMap 算法

    什么是 BigMap 算法 所谓 BitMap 就是用一个 bit 位来标记某个元素对应的 value,而 key 即是这个元素.由于采用bit为单位来存储数据,因此在可以大大的节省存储空间. 算法思 ...

  3. BitMap算法及其实现(Python)

    BitMap概述 本文介绍 BitMap 算法的应用背景,算法思想和相关实现细节. 概括而言,BitMap 主要用来解决海量数据中元素查询,去重.以及排序等问题.这里对海量数据场景的强调,似乎暗示了这 ...

  4. BitMap算法应用:Redis队列滤重优化

    工作中有用到Redis滤重队列. 原来的方法如下: 方法一 为了保证操作原子性,使用Redis执行Lua脚本. 在脚本中的逻辑是,如果队列不超过某个数值,进行一次lrem操作(队列使用list结构), ...

  5. 10个经典的C语言面试基础算法及代码

    10个经典的C语言面试基础算法及代码作者:码农网 – 小峰 原文地址:http://www.codeceo.com/article/10-c-interview-algorithm.html 算法是一 ...

  6. 数据结构C语言版 弗洛伊德算法实现

    /* 数据结构C语言版 弗洛伊德算法  P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...

  7. 经典算法题每日演练——第十一题 Bitmap算法

    原文:经典算法题每日演练--第十一题 Bitmap算法 在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美, 但是在特定的场 ...

  8. 【算法与数据结构专场】BitMap算法基本操作代码实现

    上篇我们讲了BitMap是如何对数据进行存储的,没看过的可以看一下[算法与数据结构专场]BitMap算法介绍 这篇我们来讲一下BitMap这个数据结构的代码实现. 回顾下数据的存储原理 一个二进制位对 ...

  9. 浅谈bitmap算法

    一.bitmap算法思想 32位机器上,一个整形,比如int a; 在内存中占32bit位,可以用对应的32bit位对应十进制的0-31个数,bitmap算法利用这种思想处理大量数据的排序与查询.  ...

随机推荐

  1. 组件化网页开发 / 步骤二 · 2-11 jquery的ajax方法 以及下一章跨域没懂

    1,根据2-11课程老师的提示,自己封装 $.ajax 2,第三章,跨域,没看懂

  2. JQuery 实践--让页面动起来

    获取和设置元素特性特性属性:是指DOM元素中能够和HTML元素中某个特性对应得上的属性.通常JS特性属性的名称与对应的特性一一匹配,但class <=>className操作特性还是操作属 ...

  3. 【安卓基础】使用Guideline与约束辅助布局的平分空间设计

    ConstraintLayout布局已经推出了很长一段时间,功能也是比较强大,能有效减少界面的视图层级嵌套,一定程度提升界面绘制效率. 在项目中,我也是最近才选择开始使用ConstraintLayou ...

  4. 菜鸟 Python 100例

    以下参考:菜鸟教程 python100例 == 推荐博客 有四个数字: 1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? import itertools a = ('1','2' ...

  5. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths (dsu on tree) 题解

    先说一下dsu算法. 例题:子树众数问题. 给出一棵树,每个点有点权,求每个子树中出现次数最多的数的出现次数. 树的节点数为n,\(n \leq 500000\) 这个数据范围,\(O(n \sqrt ...

  6. LNOI2018 劈配

    主要思路为连反向边. 对于本题,贪心策略,依次决定每个人的最优解 但因为每人达到的最优解可能有多种方式,如果每个都尝试就会超时,所以只能先采取其中一种 并将这个方案连反向边,其它方案连正向边 这样对于 ...

  7. jQuery.merge(first,second)

    jQuery.merge(first,second) 概述 合并两个数组 返回的结果会修改第一个数组的内容——第一个数组的元素后面跟着第二个数组的元素.要去除重复项,请使用$.unique() 参数 ...

  8. slf4j、jcl、jul、log4j1、log4j2、logback大总结[转]

    #1 系列目录 jdk-logging.log4j.logback日志介绍及原理 commons-logging与jdk-logging.log4j1.log4j2.logback的集成原理 slf4 ...

  9. tomcat控制前台到后台的乱码问题

    1.找到tomcat中的conf文件下的server.xml文件. 2.点击打开后找到 <Connector  port="8080" protocol="HTTP ...

  10. 【转】CAtlRegExp class .

    CAtlRegExp Class   CAtlRegExp 类用于表示并处理正则表达式.模板类,定义如下:     template < class CharTraits = CAtlRECha ...