Golang 实现Bit数组

前端之家收集整理的这篇文章主要介绍了Golang 实现Bit数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

**

《The Go Programming Language》 笔记

**

import (
    "bytes"
    "fmt"
)

const target int = 32 << (^uint(0) >> 63) //判断当前系统是32位还是64位

type IntSet struct {
    words []uint
}

func (s *IntSet) Has(x int) bool {
    word,bit := x/target,uint(x%target)
    return word < len(s.words) && s.words[word]&(1<<bit) != 0
}

func (s *IntSet) Add(numbers ...int) {
    for _,numebr := range numbers {
        x := numebr
        word,uint(x%target)
        for word >= len(s.words) {
            s.words = append(s.words,0)
        }
        s.words[word] |= 1 << bit
    }
}

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()
}
 //并集,合并s,t
func UnionWith(s,t *IntSet) *IntSet {
    uw := &IntSet{}
    slen,tlen := len(s.words),len(t.words)
    minlen := slen
    if minlen > tlen {
        minlen = tlen
    }
    for i := 0; i < minlen; i++ {
        uw.words = append(uw.words,s.words[i]|t.words[i])
    }
    if minlen == tlen {
        union(uw,s,minlen,slen)
    } else {
        union(uw,t,tlen)
    }
    return uw
}
 //交集,元素在s,t中均出现
func InersectWith(s,t *IntSet) *IntSet {
    iw := &IntSet{}
    slen,len(t.words)
    minlen := slen
    if minlen > tlen {
        minlen = tlen
    }
    for i := 0; i < minlen; i++ {
        iw.words = append(iw.words,s.words[i]&t.words[i])
    }
    if minlen == tlen { //s元素更多,多余的元素全部置为0
        for minlen < slen {
            iw.words = append(iw.words,s.words[minlen]&0)
            minlen++
        }
    }
    return iw
}
 //差集,元素出现在s,未出现在t
func DifferenceWith(s,t *IntSet) *IntSet {
    dw := &IntSet{}
    slen,len(t.words)
    minlen := slen
    if minlen > tlen {
        minlen = tlen
    }
    for i := 0; i < minlen; i++ {
        mask := s.words[i] & t.words[i]
        dw.words = append(dw.words,s.words[i]^mask)
    }
    if minlen == tlen && minlen < slen {
        union(dw,slen)
    }
    return dw
}
 //并差集,元素出现在s但未出现在t,或者元素出现在t但未出现在s
func SymmetricDifference(s,t *IntSet) *IntSet {
    sd := &IntSet{}
    slen,len(t.words)
    minlen := slen
    if minlen > tlen {
        minlen = tlen
    }
    for i := 0; i < minlen; i++ {
        sd.words = append(sd.words,s.words[i]^t.words[i])
    }
    if minlen == tlen {
        union(sd,slen)
    } else {
        union(sd,tlen)
    }
    return sd
}
 //从tmplen开始,将is中的元素复制到res
func union(res,is *IntSet,tmplen,xlen int) {
    for tmplen < xlen {
        res.words = append(res.words,is.words[tmplen])
        tmplen++
    }
}

func main() {
    var x,y IntSet
    x.Add(0)
    x.Add(1,3,5,7)
    x.Add(9)
    x.Add(63)
    x.Add(100)
    fmt.Println("x : ",x.String())

    y.Add(9)
    y.Add(42)
    y.Add(7)
    y.Add(5)
    fmt.Println("y : ",y.String())

    result1 := UnionWith(&x,&y)
    fmt.Println("x UnionWith y : ",result1.String())
    result2 := InersectWith(&x,&y)
    fmt.Println("x InersectWith y : ",result2.String())
    result3 := DifferenceWith(&x,&y)
    fmt.Println("x DifferenceWith y : ",result3.String())
    result4 := SymmetricDifference(&x,&y)
    fmt.Println("x SymmetricDifference y : ",result4.String())

}
原文链接:https://www.f2er.com/go/189156.html

猜你在找的Go相关文章