【记录】位向量

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个元素

再使用位操作 操作数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值