Skip to content

Commit aeb513b

Browse files
committed
feat: 增加布尔数组类型
1 parent c371458 commit aeb513b

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

pkg/bool_array/array.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package bool_array
2+
3+
import (
4+
"fmt"
5+
if_expression "github.com/golang-infrastructure/go-if-expression"
6+
)
7+
8+
type BoolArray struct {
9+
values []byte
10+
capacity int
11+
}
12+
13+
// New 创建一个布尔数组
14+
func New(capacity int) *BoolArray {
15+
16+
if capacity < 0 {
17+
panic(fmt.Errorf("capacity %d is invalid", capacity))
18+
}
19+
20+
return &BoolArray{
21+
// 预分配容量
22+
values: make([]byte, (capacity+7)/8),
23+
capacity: capacity,
24+
}
25+
}
26+
27+
// 检查下标是否合法,比如越界检查之类的
28+
func (x *BoolArray) checkIndex(indexes ...int) {
29+
for _, index := range indexes {
30+
if index < 0 || index >= x.capacity {
31+
panic(fmt.Errorf("index %d out of bound", index))
32+
}
33+
}
34+
}
35+
36+
// FillAll 把布尔数组所有的值都填充为给定的值
37+
func (x *BoolArray) FillAll(value bool) *BoolArray {
38+
return x.Fill(0, x.capacity, value)
39+
}
40+
41+
// Fill 往给定的左开右闭区间填充给定的值
42+
func (x *BoolArray) Fill(fromIndex, toIndex int, value bool) *BoolArray {
43+
44+
x.checkIndex(fromIndex, toIndex)
45+
46+
for fromIndex < toIndex {
47+
x.Set(fromIndex, value)
48+
}
49+
return x
50+
}
51+
52+
// Set 设置给定位置的值
53+
func (x *BoolArray) Set(index int, v bool) *BoolArray {
54+
55+
x.checkIndex(index)
56+
57+
targetIndex := index / 8
58+
offset := index % 8
59+
byteValue := byte(if_expression.Return(v, 1, 0))
60+
// 除了offset其它位置都原样拷贝
61+
oldByte := x.values[targetIndex] ^ (1 << offset)
62+
newByte := oldByte | (byteValue << offset)
63+
x.values[targetIndex] = newByte
64+
return x
65+
}
66+
67+
// Get 获取给定下标位置当前存储的布尔值
68+
func (x *BoolArray) Get(index int) bool {
69+
70+
x.checkIndex(index)
71+
72+
targetIndex := index / 8
73+
offset := index % 8
74+
intValue := (int(x.values[targetIndex]) >> offset) & 0x01
75+
return if_expression.Return(intValue == 1, true, false)
76+
}
77+
78+
// ToBinaryString 把数组转为二进制字符串形式
79+
func (x *BoolArray) ToBinaryString() string {
80+
runes := make([]rune, x.capacity)
81+
// TODO 效率更高的遍历方式
82+
for index := 0; index < x.capacity; index++ {
83+
runes[index] = if_expression.Return(x.Get(index), '1', '0')
84+
}
85+
return string(runes)
86+
}

pkg/bool_array/array_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package bool_array
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
func TestNew(t *testing.T) {
9+
assert.Equal(t, "0", New(1).ToBinaryString())
10+
assert.Equal(t, "00", New(2).ToBinaryString())
11+
assert.Equal(t, "000", New(3).ToBinaryString())
12+
assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", New(1024).ToBinaryString())
13+
}
14+
15+
func TestBoolArray_Set(t *testing.T) {
16+
array := New(10)
17+
array.Set(1, true)
18+
assert.Equal(t, "0100000000", array.ToBinaryString())
19+
20+
for i := 2; i < 10; i++ {
21+
array.Set(i, true)
22+
}
23+
assert.Equal(t, "0111111111", array.ToBinaryString())
24+
}
25+
26+
func TestBoolArray_Get(t *testing.T) {
27+
array := New(12)
28+
array.Set(10, true)
29+
value := array.Get(10)
30+
assert.Equal(t, true, value)
31+
}

0 commit comments

Comments
 (0)