「GoCN酷Go推荐」go语言位操作库 — bitset

共 2482字,需浏览 5分钟

 ·

2022-01-09 23:41

bitset库实现了bitsets数据结构,这是一种正整数和布尔值映射关系的结构,它比map[uint]bool更高效

什么是bitsets

bitsets基本思想是用一个bit位来标记某个元素对应的Value,每一位表示一个数,1表示存在,0表示不存在 比如我要表示1, 3, 7这3个数

  1. 构造一个空白bitsets:00000000
  2. 每位代表的值如下:76543210
  3. 想要表示的值标记1:10001010

有什么好处?

最大的好处是节省存储空间,假设有20亿个正整数中找出m是否在其中 如果每个数字用int存储,占8byte,2000000000 * 8 = 14G 如果用bit存储每个数字,占1bit,2000000000 / 8 = 0.233G 由此可见bitsets节省了极大的存储空间

Usage

  1. 安装
go get github.com/bits-and-blooms/bitset
  1. 基本操作
// 构造一个64bit长度的bitset
b := bitset.New(64)
// 放入一个数
b.Set(10)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000010000000000
// 删除一个值
b.Clear(10)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000000000000000
// 长度
b.Set(1).Set(3)
fmt.Println(b.Len()) // 64
// 测试
fmt.Println(b.Test(3)) // true
fmt.Println(b.Test(4)) // false
  1. 指定位置操作
b := &bitset.BitSet{}
b.Set(3)
// 在指定位置插入0
b.InsertAt(3)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000000000010000
// 在指定位置修改
b.SetTo(4false)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000000000000000
// 指定位置删除
b.Set(3).DeleteAt(3// 000000000000000000000000000000000000000000000000000000000000
  1. 两个bitsets交互
a := &bitset.BitSet{}
a.Set(1).Set(3).Set(5)
b := &bitset.BitSet{}
b.Set(3).Set(5).Set(7)
// 交集
fmt.Println(a.Intersection(b)) // {3,5}
// 并集
fmt.Println(a.Union(b)) // {1,3,5,7}
// 差集
fmt.Println(a.Difference(b)) // {1}
// 全等
fmt.Println(a.Equal(b)) // false
  1. 遍历
b := bitset.New(64)
b.Set(1).Set(3).Set(5).Set(7)
for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {
    fmt.Println("The following bit is set:", i)
}
// The following bit is set: 1
// The following bit is set: 3
// The following bit is set: 5
// The following bit is set: 7

实例

假设现在数据库里有一个字段存储用户状态,设计是这样的:0 00 00 第1、2位表示会员等级 00表示普通会员,01表示vip1,10表示vip2,11表示svip 第3、4位表示头像状态 00表示未上传,01表示01审核中,10审核失败,11审核通过 第5位表示账号状状态 0表示正常,1表示封禁

b := bitset.New(5)
// 设置vip1,第1位0,第2位1
b.SetTo(1false).SetTo(2true)

// 设置头像审核失败,第3位1,第4位0
b.SetTo(3true).SetTo(4false)

// 状态初始化
b.ClearAll()

// 查看账号状态,第5位,true代表1 false代表0
b.Test(5

// 是不是svip,第1、2位是11
b.Test(1) && b.Test(2)

总结

bitset/bitmap在日常开发中会经常用到,在特定场景下有很好的效果。这个库可以简化操作bitset/bitmap的难度,而且这个库的源码也很好的演示了go的位操作

官方文档:https://github.com/bits-and-blooms/bitset


《酷Go推荐》招募:


各位Gopher同学,最近我们社区打算推出一个类似GoCN每日新闻的新栏目《酷Go推荐》,主要是每周推荐一个库或者好的项目,然后写一点这个库使用方法或者优点之类的,这样可以真正的帮助到大家能够学习到

新的库,并且知道怎么用。


大概规则和每日新闻类似,如果报名人多的话每个人一个月轮到一次,欢迎大家报名!戳「阅读原文」,即可报名


扫码也可以加入 GoCN 的大家族哟~


浏览 34
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报