package main
import(
"fmt"
"bytes"
)
type IntSet struct{
words []uint64
}
func (s *IntSet)Has(x int)bool{
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
func (s *IntSet)Add(x int){
word, bit := x/64, uint(x%64)
for word >= len(s.words){
s.words = append(s.words, 0)
}
s.words[word] |= 1<<bit
}
func (s *IntSet)UnionWith(t *IntSet){
for i, tword := range t.words{
if i < len(s.words){
s.words[i] |= tword
}else{
s.words = append(s.words, tword)
}
}
}
func (s *IntSet)String()string{
var buf bytes.Buffer
buf.WriteByte('{')
for i, word := range s.words{
if word == 0{
continue
}
for j := 0; j<64; j++{
if word&(1<<j)!=0{
if buf.Len() > len("{"){
buf.WriteByte(' ')
}
fmt.Fprintf(&buf, "%d", 64*i+j)
}
}
}
buf.WriteByte('}')
return buf.String()
}
func (s *IntSet)Len()int{
ans := 0
for _, word := range s.words{
if word == 0{
continue
}
for j := 0; j<64; j++{
if word&(1<<j)!=0{
ans++
}
}
}
return ans
}
func (s *IntSet)Remove(x int){
word, bit := x/64, uint(x%64)
if s.Has(x){
s.words[word] ^= 1<<bit
}else{
fmt.Println("x is not in s")
}
}
func main(){
var x,y IntSet
x.Add(1)
x.Add(144)
x.Add(9)
fmt.Println(x.String())
y.Add(9)
y.Add(42)
x.UnionWith(&y)
fmt.Println(x.String())
fmt.Println(len(x.words))
fmt.Println(x.Len())
x.Remove(14)
x.Remove(144)
fmt.Println(&x)
}
/*
output:
{1,9,144}
{1,9,42,144}
3
4
x is not in s
{1,9,42}
*/
位向量用来表示元素是否存在,第i位为1则表示第i个元素存在,使用64位无符号整数数组表示。则一个数组元素可表示64个元素是否存在。
使用word, bit := x/64, uint(x%64)定位是数组的哪一个元素和第几位。
通过(1<<bit)寻找到第i个元素
再使用位操作 操作数组