用bit数组构建集合

用bit位来构建集合,查找插入重复数据效率都非常高。

type IntSet struct {
    words []uint64
}

// Has reports whether the set contains the non-negative value x.
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
}

// Add adds the non-negative value x to the set.
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
}

// remove x
func (s *IntSet) Remove(x int) int {
    word, bit := x/64, uint(x%64)
    if word >= len(s.words) {
        return -1 //不存在
    }
    s.words[word] &= ^(1 << bit)
    return 0
}

// UnionWith sets s to the union of s and t.
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) InterWith(t *IntSet) {
    for i, tword := range t.words {
        if i < len(s.words) {
            s.words[i] &= tword
        }
    }
}
// 长度
func (s *IntSet) Len() (len int) {
    for _, tword := range s.words {
        if tword == 0 {
            continue
        }
        for j := 0; j < 64; j++ {
            if tword&(1<<uint(j)) != 0 {
                len++
            }
        }
    }
    return
}
// 转换成string,便于查看
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<<uint(j)) != 0 { //判断这一位是否存在
                if buf.Len() > len("{") { //不是第一位就加空格
                    buf.WriteByte(' ')
                }
                fmt.Fprintf(&buf, "%d", 64*i+j)
            }
        }
    }
    buf.WriteByte('}')
    return buf.String()
}
// 复制
func (s *IntSet) Copy() (res *IntSet) {
    res = &IntSet{}
    res.words = make([]uint64, len(s.words))
    copy(res.words, s.words)
    return
}
// 清空
func (s *IntSet) Clear() {
    for i := range s.words {
        s.words[i] &= 0
    }
}

以上算法都基于bit运算,包括与,或,异或

原文地址:https://www.cnblogs.com/peterleee/p/13892030.html