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算法利用这种思想处理大量数据的排序与查询. ...
随机推荐
- GDI+ 实例:绘制验证码
一.概述 一般处理程序 ashx :它没有服务器控件,用response输出什么就是什么. 生成验证码原理:产生随机字符,并将字符生成为图片,同时储存到Session里去,然后验证用户输入的内容是否与 ...
- php文件更新后不生效?亲测有效!
1,问题描述 一台windows Server2008 服务器上运行了iis7,其中存在php5.3和php5.5引擎的网页服务. 但实际使用中发现,修改php文件后,访问该文件的结果经常不能实时刷新 ...
- mysql常用的索引种类
一.索引 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度 二.索引类型 Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RT ...
- CF788C The Great Mixing BFS+思维
这个模型十分巧妙啊,好题好题~ code: #include <bits/stdc++.h> #define N 3006 #define setIO(s) freopen(s" ...
- bzoj 3545
bzoj 3555 离线版本 线段树合并 做法是将询问和边权都排序 给每个点建一棵线段树 然后边建mst边回答询问 每次合并两个连通块的时候 要将两个连通块的线段树合并起来 线段树合并部分code i ...
- [Luogu] 兽径管理
题面:https://www.luogu.org/problemnew/show/P1340 题解:https://www.zybuluo.com/wsndy-xx/note/1153773
- DRF-视图类组件
补充 GET books-------->查看数据--------------------> 返回所有数据列表 :[{},{},{}] POST books-------->添加数 ...
- const char*p,char const*p,char *const p
转自 http://blog.csdn.net/todd911/article/details/7911995 const char*, char const*, char*const的区别问题几乎是 ...
- 深入理解D3D9
本文写的较为深入,故转载在此留以备案,呵呵~ 原文链接为:http://www.cnblogs.com/effulgent/archive/2009/02/10/1387438.html ------ ...
- MySQL数据分析(7)-SQL的两大学习框架
大家好,我是jacky,很高兴继续跟大家分享<MySQL数据分析实战>课程,前面的课程基本上我把MySQL的原理都做了一定的介绍,有好多朋友说学习MySQL是没有逻辑的,其实jacky是非 ...