bitset库
实现了bitsets
数据结构,这是一种正整数和布尔值映射关系的结构,它比map[uint]bool
更高效
什么是bitsets?
bitsets基本思想是用一个bit位来标记某个元素对应的Value,每一位表示一个数,1表示存在,0表示不存在 比如我要表示1, 3, 7这3个数
构造一个空白bitsets:00000000
每位代表的值如下:76543210
想要表示的值标记1:10001010
有什么好处??
最大的好处是节省存储空间,假设有20亿个正整数中找出m是否在其中 如果每个数字用int存储,占8byte,2000000000 * 8 = 14G 如果用bit存储每个数字,占1bit,2000000000 / 8 = 0.233G 由此可见bitsets节省了极大的存储空间
Usage?
安装
go get github.com/bits-and-blooms/bitset
基本操作
// 构造一个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
指定位置操作
b := &bitset.BitSet{}
b.Set(3)
// 在指定位置插入0
b.InsertAt(3)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000000000010000
// 在指定位置修改
b.SetTo(4, false)
fmt.Println(b.DumpAsBits()) // 000000000000000000000000000000000000000000000000000000000000
// 指定位置删除
b.Set(3).DeleteAt(3) // 000000000000000000000000000000000000000000000000000000000000
两个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
遍历
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(1, false).SetTo(2, true)// 设置头像审核失败,第3位1,第4位0
b.SetTo(3, true).SetTo(4, false)// 状态初始化
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 的大家族哟~