位运算——IntSet

type IntSet struct {
	words  []uint
	length int
}

func  (s *IntSet) Has(x int)  bool {
	word, bit := x / (32 << (^uint(0) >> 63)), x % (32 << (^uint(0) >> 63)) // 确定平台的无符号类型是32位还是64位: (32 << (^uint(0) >> 63))
	return word < len(s.words) && s.words[word] & (1 << bit) != 0
}

func (s *IntSet) Add(x int)  {
	word, bit := x / (32 << (^uint(0) >> 63)), x % (32 << (^uint(0) >> 63))
	for word >= len(s.words) {
		s.words = append(s.words,0)
	}
	s.words[word] |= 1 << bit
	s.length++
}

func (s *IntSet) UnionWith(t *IntSet)  {
	for i, tWord := range t.words {
		if i < len(s.words) {
			s.length += getOneBitsCount(s.words[i] ^ (s.words[i] | tWord))
			s.words[i] |= tWord
		}else {
			s.length += getOneBitsCount(tWord)
			s.words = append(s.words, tWord)
		}
	}
}

func getOneBitsCount(x uint) int {
	ans := 0
	for x != 0 {
		x &= x - 1
		ans++
	}
	return ans
}

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 < (32 << (^uint(0) >> 63)); j++ {
			if word&(1 << uint(j)) != 0 {
				if buf.Len() > len("{"){
					buf.WriteByte(' ')
				}
				_, _ = fmt.Fprintf(&buf,"%d",(32 << (^uint(0) >> 63)) * i + j)
			}
		}
	}
	buf.WriteByte('}')
	return buf.String()
}

func (s *IntSet) Len() int {
	return s.length
}

func (s *IntSet) Remove(x int) {
	word, bit := x / (32 << (^uint(0) >> 63)), x % (32 << (^uint(0) >> 63))
	s.words[word] &^= 1 << bit
	s.length--
}

func (s *IntSet) Clear()  {
	s.words = s.words[:0]
	s.length = 0
}

func (s *IntSet) Copy() *IntSet {
	return &IntSet{
		words:  s.words,
		length: s.length,
	}
}

func main() {
	var x, y IntSet
	x.Add(1)
	x.Add(2)
	x.Add(3)
	x.Add(9)
	x.Add(144)

	x.Add(1 << 2 )

	 for i := 100; i < 9999; i++ {
		 x.Add(i)
	 }
	//fmt.Println(x.String())

	y.Add(42)
	y.Add(1)
	y.Add(2)
	y.Add(9)
	//fmt.Println(y.String())

	x.UnionWith(&y)
	fmt.Println(x)
	fmt.Println(x.Has(10 - 1))
	fmt.Println(x.Len())
	x.Remove(1)
	 fmt.Println(x)
	for i := 100; i < 9999; i++ {
		x.Remove(i)
	}
	 fmt.Println(x)

	fmt.Println(x)

	x1 := x.Copy()
	x.Clear()
	fmt.Println(x)
	fmt.Println(x1)
}

核心思想:用1bit代表一个数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值