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) Intersection(n *BitMap) *BitMap { // 交集
intersection := new(BitMap)
var small, big = b, n
if len(*small) > len(*big) {
small, big = big, small
}
for index, bits := range *small {
for j := 0; j < machineWord; j++ {
if num := index*machineWord + j; (bits>>j)&1 == 1 && big.Has(num) {
intersection.Add(num)
}
}
}
return intersection
}
func (b *BitMap) Union(n *BitMap) *BitMap {
var small, big = b, n
if len(*small) > len(*big) {
small, big = big, small
}
union := big.Copy()
for i, tWord := range *small {
(*union)[i] |= tWord
}
return union
}
func (b *BitMap) Subtraction(n *BitMap) *BitMap {
sub := b.Copy()
for index, bits := range *n {
for j := 0; j < machineWord; j++ {
if num := index*machineWord + j; (bits>>j)&1 == 1 {
sub.Remove(num)
}
}
}
return sub
}
func (b *BitMap) ComplementSet(n *BitMap) *BitMap {
if len(*b) < len(*n) {
return &BitMap{}
}
com := b.Copy()
for index, bits := range *n {
for j := 0; j < machineWord; j++ {
if num := index*machineWord + j; (bits>>j)&1 == 1 {
if com.Has(num) {
com.Remove(num)
} 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.Intersection(&y))
fmt.Println("x y 并集", x.Union(&y))
fmt.Println("x y 差集", x.Subtraction(&y))
fmt.Println("y x 差集", y.Subtraction(&x))
fmt.Println("x y 补集", x.ComplementSet(&y))
fmt.Println("y x 补集", y.ComplementSet(&x))
x.Clear()
fmt.Println(&x)
}
见加速版本