《go语言圣经》练习答案--第六章

练习6.1: 为bit数组实现下面这些方法

func (*IntSet) Len() int      // return the number of elements
func (*IntSet) Remove(x int)  // remove x from the set
func (*IntSet) Clear()        // remove all elements from the set
func (*IntSet) Copy() *IntSet // return a copy of the set
func (s *IntSet) Len() int {
	ret := 0
	for i, word := range s.words {
		if word == 0 {
			continue
		}
		for j := 0; i < 64; j++ {
			if word&(1<<uint(j)) != 0 {
				ret++
			}
		}
	}
	return ret
}
func (s *IntSet) Remove(x int) {
	word, bit := x/64, uint(x%64)
	s.words[word] &= (^(1 << bit))
}
func (s *IntSet) Clear() {
	s.words = s.words[:0]
}
func (s *IntSet) Copy() *IntSet {
	newWords := make([]uint64, len(s.words))
	copy(newWords, s.words)
	return &IntSet{newWords}
}

练习 6.2: 定义一个变参方法(*IntSet).AddAll(...int),这个方法可以添加一组IntSet,比如s.AddAll(1,2,3)。

func (s *IntSet) AddALL(values ...int) {
	for _, v := range values {
		s.Add(v)
	}
}

练习 6.3: (*IntSet).UnionWith会用|操作符计算两个集合的交集,我们再为IntSet实现另外的几个函数IntersectWith(交集:元素在A集合B集合均出现),DifferenceWith(差集:元素出现在A集合,未出现在B集合),SymmetricDifference(并差集:元素出现在A但没有出现在B,或者出现在B没有出现在A)。

func (s *IntSet) And(t *IntSet) {
	min := math.Min(len(s.words), len(t.words))
	for i := 0; i < min; i++ {
		s.words[i] &= t.words[i]
	}
	s.words = s.words[:min]
}

练习6.4: 实现一个Elems方法,返回集合中的所有元素,用于做一些range之类的遍历操作。

func (s *IntSet) Elems() []int {
	var ret []int
	for i, word := range s.words {
		if word == 0 {
			continue
		}
		for j := 0; j < 64; j++ {
			if word&(1<<uint(j)) != 0 {
				ret = append(ret, 64*i+j)
			}
		}
	}
	return ret
}
posted @ 2022-03-24 11:50  随风而逝的白色相簿  阅读(169)  评论(0编辑  收藏  举报