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算法利用这种思想处理大量数据的排序与查询. ...
随机推荐
- STM32串口接收中断——基于HAL库
写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...
- Sort a list(tuple,dict)
FROM:https://www.pythoncentral.io/how-to-sort-python-dictionaries-by-key-or-value/ AND https://www.p ...
- //点击按钮加减音频音量到最小会出现bug什么意思???
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Appium自动化测试教程-自学网-monkey参数
monkey 参数 参数分类 · 常规类参数 · 事件类参数 · 约束类参数 · 调试类参数 常规类参数 常规类参数包括帮助参数和日志信息参数.帮助参数用于输出Monkey命令使用指导:日志信息参数将 ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) C. Save the Nature【枚举二分答案】
https://codeforces.com/contest/1241/problem/C You are an environmental activist at heart but the rea ...
- deferred.pipe([doneFilter],[failFilter],[progressFilter])
deferred.pipe([doneFilter],[failFilter],[progressFilter]) 概述 筛选器和/或链Deferreds的实用程序方法. deferred.pipe( ...
- learning express step(一)
first : create new project then install express package : npm install express --savenpm WARN saveErr ...
- 51nod 1076
* 无向图的割边将图分为不连通的两部分 * 对于是否有不想交的两条路径将s -> t 相连 * 只需判断是否处于同一部分 * Tarjan即可 #include <bits/stdc++. ...
- 2018 Nowcoder Multi-University Training Contest 10
Practice Link J. Rikka with Nickname 题意: 给出\(n\)个字符串,要求依次合并两个串\(s, t\),满足将\(t\)合并到\(s\)中变成\(r\),使得\( ...
- seq2seq聊天模型(三)—— attention 模型
注意力seq2seq模型 大部分的seq2seq模型,对所有的输入,一视同仁,同等处理. 但实际上,输出是由输入的各个重点部分产生的. 比如: (举例使用,实际比重不是这样) 对于输出"晚上 ...