分享
  1. 首页
  2. 文章

golang实现的bitmap,增减查元素,附单元测试

yanglikai · · 1236 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

bitmap.go

package ...
import (
	"bytes"
	"fmt"
)
type Bitmap struct {
	//按64*i取模后得到的值(i为数组元素下标)
	modValues []uint64
	length int
}
func (bitmap *Bitmap) IsExist(num int) bool {
	floor, bit := num/64, uint(num%64)
	return floor < len(bitmap.modValues) && (bitmap.modValues[floor]&(1<<bit)) != 0
}
//加入一个数,返回值:是否操作成功,true:本身不存在,加入成功;false:本身已存在
func (bitmap *Bitmap) Add(num int) bool {
	floor, bit := num/64, uint(num%64)
	isExist := false
	for floor >= len(bitmap.modValues) {
		bitmap.modValues = append(bitmap.modValues, 0)
		isExist = true
	}
	//余数转成对应bit位的值
	remainder := uint64(1<<bit)
	// 判断num是否已经存在bitmap中
	if !isExist && bitmap.modValues[floor] & remainder != 0 {
		return false
	}
	isExist = true
	//余数对应的bit位值置为1
	bitmap.modValues[floor] |= remainder
	bitmap.length++
	return isExist
}
//去掉一个数,返回值:是否操作成功,true:本身存在,被删除;false:本身就不存在
func (bitmap *Bitmap) Sub(num int) bool {
	floor, bit := num/64, uint(num%64)
	for floor >= len(bitmap.modValues) {
		return false
	}
	// 判断num是否已经存在bitmap中,不存在直接返回false
	if bitmap.modValues[floor] & (1<<bit) == 0 {
		return false
	}
	//余数对应的bit位值置为0
	bitmap.modValues[floor] -= 1 << bit
	bitmap.length--
	return true
}
func (bitmap *Bitmap) Len() int {
	return bitmap.length
}
func (bitmap *Bitmap) String() string {
	var buf bytes.Buffer
	buf.WriteByte('{')
	for i, v := range bitmap.modValues {
		if v == 0 {
			continue
		}
		uinti := uint(i)
		for j := uint(0); j < 64; j++ {
			if v & (1<<j) != 0 {
				if buf.Len() > 1 {
					buf.WriteByte(',')
				}
				fmt.Fprintf(&buf, "%d", 64 * uinti + j)
			}
		}
	}
	buf.WriteByte('}')
	fmt.Fprintf(&buf,"\nLength: %d", bitmap.length)
	return buf.String()
}

单元测试(bitmap_test.go):

package ...
import (
	"fmt"
	. "github.com/smartystreets/goconvey/convey"
	"testing"
)
func Test_Bitmap(t *testing.T) {
	Convey("test Bitmap", t, func() {
		bitmap := new(Bitmap)
		So(bitmap.Add(3), ShouldBeTrue)
		So(len(bitmap.modValues) == 1, ShouldBeTrue)
		//fmt.Println(bitmap.String())
		
		So(bitmap.length == 1, ShouldBeTrue)
		So(bitmap.Add(5), ShouldBeTrue)
		So(len(bitmap.modValues) == 1, ShouldBeTrue)
		So(bitmap.length == 2, ShouldBeTrue)
		So(bitmap.Add(63), ShouldBeTrue)
		So(len(bitmap.modValues) == 1, ShouldBeTrue)
		So(bitmap.length == 3, ShouldBeTrue)
		So(bitmap.Add(64), ShouldBeTrue)
		So(len(bitmap.modValues) == 2, ShouldBeTrue)
		So(bitmap.Add(127), ShouldBeTrue)
		So(len(bitmap.modValues) == 2, ShouldBeTrue)
		So(bitmap.length == 5, ShouldBeTrue)
		So(bitmap.Add(128), ShouldBeTrue)
		So(len(bitmap.modValues) == 3, ShouldBeTrue)
		So(bitmap.Add(256), ShouldBeTrue)
		So(len(bitmap.modValues) == 256/64+1, ShouldBeTrue)
		So(bitmap.Add(511), ShouldBeTrue)
		So(len(bitmap.modValues) == 512/64, ShouldBeTrue)
		So(bitmap.length == 8, ShouldBeTrue)
		So(bitmap.Add(513), ShouldBeTrue)
		So(len(bitmap.modValues) == 512/64+1, ShouldBeTrue)
		So(bitmap.length == 9, ShouldBeTrue)
		//fmt.Println(bitmap.Add(63))
		fmt.Println(bitmap.String())
		So(bitmap.Add(63), ShouldBeFalse)
		So(len(bitmap.modValues) == 512/64+1, ShouldBeTrue)
		So(bitmap.length == 9, ShouldBeTrue)
		So(bitmap.Sub(632), ShouldBeFalse)
		So(len(bitmap.modValues) == 512/64+1, ShouldBeTrue)
		So(bitmap.length == 9, ShouldBeTrue)
		So(bitmap.Sub(63), ShouldBeTrue)
		So(len(bitmap.modValues) == 512/64+1, ShouldBeTrue)
		So(bitmap.length == 8, ShouldBeTrue)
		So(bitmap.Sub(513), ShouldBeTrue)
		So(len(bitmap.modValues) == 512/64+1, ShouldBeTrue)
		So(bitmap.length == 7, ShouldBeTrue)
	})
}

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1236 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏