package main
import (
"bytes"
"fmt"
)
const machineWord = 32 << (^uint(0) >> 63) //确定平台的无符号类型是32位还是64位: (32 << (^uint(0) >> 63))
type BitMap []uint
func (b *BitMap) Has(x int) bool {
word, bit := x/machineWord, x%machineWord
return word < len(*b) && (*b)[word]&(1<<bit) != 0
}
func (b *BitMap) Add(x int) {
word, bit := x/machineWord, x%machineWord
for word >= len(*b) {
*b = append(*b, 0, 0, 0, 0)
}
(*b)[word] |= 1 << bit
}
func (b *BitMap) IntersectionSet(n *BitMap) *BitMap { // 交集
small, big := b, n
if len(*small) > len(*big) {
small, big = big, small
}
intersection := small.Copy()
for i := 0; i < len(*small); i++ {
(*intersection)[i] &= (*big)[i]
}
return intersection
}
func (b *BitMap) UnionSet(n *BitMap) *BitMap {
var small, big = b, n
if len(*small) > len(*big) {
small, big = big, small
}
union := big.Copy()
for i := 0; i < len(*small); i++ {
(*union)[i] |= (*small)[i]
}
return union
}
func (b *BitMap) SubtractionSet(n *BitMap) *BitMap {
sub := b.Copy()
for i := 0; i < len(*b) && i < len(*n); i++ {
(*sub)[i] &= ^(*n)[i]
}
return sub
}
func (b *BitMap) ComplementSet(n *BitMap) *BitMap {
if len(*b) < len(*n) {
return &BitMap{}
}
com := b.Copy()
for i := 0; i < len(*n); i++ {
if (*com)[i]&(*n)[i] == (*n)[i] {
(*com)[i] ^= (*n)[i]
} else {
return &BitMap{}
}
}
return com
}
func (b *BitMap) String() string {
var buf bytes.Buffer
buf.WriteByte('[')
for i, word := range *b {
if word == 0 {
continue
}
for j := 0; j < machineWord; j++ {
if word&(1<<uint(j)) != 0 {
if buf.Len() > 1 {
buf.WriteByte(' ')
}
_, _ = fmt.Fprintf(&buf, "%d", machineWord*i+j)
}
}
}
buf.WriteByte(']')
return buf.String()
}
func (b *BitMap) Len() int {
return len(*b)
}
func (b *BitMap) Remove(x int) {
word, bit := x/machineWord, x%machineWord
if word >= len(*b) {
return
}
(*b)[word] &^= 1 << bit
}
func (b *BitMap) Clear() {
*b = (*b)[:0]
}
func (b *BitMap) Copy() *BitMap {
n := make(BitMap, len(*b))
copy(n, *b)
return &n
}
func main() {
var x, y BitMap
x.Add(1)
x.Add(2)
x.Add(3)
x.Add(9)
x.Add(144)
x.Add(1 << 2)
x.Add(7)
x.Add(99999999)
y.Add(1)
y.Add(2)
y.Add(7)
y.Add(99999999)
fmt.Println("x", &x)
fmt.Println("y", &y)
fmt.Println("x y 交集", x.IntersectionSet(&y))
fmt.Println("x y 并集", x.UnionSet(&y))
fmt.Println("x y 差集", x.SubtractionSet(&y))
fmt.Println("y x 差集", y.SubtractionSet(&x))
fmt.Println("x y 补集", x.ComplementSet(&y))
fmt.Println("y x 补集", y.ComplementSet(&x))
x.Clear()
//fmt.Println(&x)
}
search——bitmap的交并差补,加速版,位运算
于 2022-12-08 00:40:28 首次发布