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算法利用这种思想处理大量数据的排序与查询. ...
随机推荐
- C# 截图不失真
Bitmap bmp = new Bitmap(@"E:\2222.jpg"); Bitmap bmp2 = bmp.Clone(new Rectangle(10 + 80, 15 ...
- pandas处理json脱坑(一)--JsonError: Expecting property name enclosed in double quotes
python执行json.loads(…)时遇到的错误json格式的文本中应该用双引号,而不是单引号,如: brief=json.loads(row["brief"].replac ...
- 洛谷1546 最短网络Agri-Net【最小生成树】【prim】
[内含最小生成树Prim模板] 题目:https://www.luogu.org/problemnew/show/P1546 题意:给定一个邻接矩阵.求最小生成树. 思路:点少边多用Prim. Pri ...
- 边学边体验django--HttpRequest 对象
每个view函数的第一个参数是一个HttpRequest对象. HttpRequest对象包含当前请求URL的一些信息: 属性 描述 path 请求页面的全路径,不包括域名'/hello/' meth ...
- yii 查询垃圾分类接口
public function actionGarbage() { // $param = \Yii::$app->request->post('rubbish', ''); // 接收j ...
- 001_UCOSIII引入原因
(一)在前年的学习中一直都是在裸机上跑程序的,根本没有用到操作系统,但是因为以前开发的东西很小,根本用不着,也没必要在操作系统上跑,所以就没有学习.在未来的几天中将进军UCOSIII.为什么选择UCO ...
- [USACO5.5] 矩形周长Picture
https://www.luogu.org/problemnew/show/P1856 1.每个矩形由两条横向边和两条纵向边组成. 2.对于横向边,按纵坐标排序.设当前讨论的边为 A [s , t] ...
- About Grisha N. ( URAL - 2012 )
Problem Grisha N. told his two teammates that he was going to solve all given problems at the subreg ...
- k8s之yaml详解
k8s之yaml详解 apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数 ...
- 【零基础】AI神经元解析(含实例代码)
一.序言 关于“深度学习”大部分文章讲的都云里雾里,直到看到“床长”的系列教程以及<深度学习入门:基于Python的理论与实现>,这里主要是对这两个教程进行个人化的总结,目标是让“0基础” ...