Go 位向量示例

本文介绍了一种使用位操作来高效实现整数集合的方法,包括添加、删除、求交集、并集等操作,并通过具体示例展示了这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Example:

package main

/*
    Created by Marco 2017.12.26 22:52
*/

import (
    "fmt"
    "bytes"
)

type IntSet struct {
    words []uint64
}

/*
    determine the existence of this element
*/
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 elements to the collection
*/
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
}

/*
    print the element of the slice
*/
func (s *IntSet) Print() {
    for _,v := range s.words {
        fmt.Println(v)
    }
}

/*
    convert the collection to 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()
}

/*
    seek two sets of union
*/
func (s *IntSet) UnionWidth(t *IntSet) {
    for i,tword := range t.words {
        if i < len(s.words) {
            s.words[i] |= tword
        }else {
            s.words = append(s.words,tword)
        }
    }
}
/*
    add all the elements to collection
*/
func (s *IntSet) AddAll(vals ...int) {
    for _,v := range vals {
        s.Add(v)
    }
}

/*
    get the length of collection
*/
func (s *IntSet) Len() int {
    var length int = 0
    for _,word := range s.words {
        if word == 0 {
            continue
        }
        for j := 0; j < 64; j++ {
            if word  & (1 << uint(j)) != 0 {
                length++
            }
        }
    }
    return length
}

/*
    remove one element of the collection
*/
func (s *IntSet) Remove(x int) {
    word,bit := x/64,x%64
    s.words[word] ^= (1 << uint(bit))
}

/*
    clear the collection
*/
func (s *IntSet) Clear() {
    for i,_ := range s.words {
        s.words[i] = 0
    }
}

/*
    copy the collection
*/
func (s *IntSet) Copy() (*IntSet) {
    var ret IntSet
    for _,word := range s.words {
        ret.words = append(ret.words,word)
    }
    return &ret
}

/*
    get the intersection of the two sets
*/
func (s *IntSet) AndWith(t *IntSet) {
    for i,_ := range t.words {
        if i < len(t.words) {
            s.words[i] &= t.words[i]
        }else {
            s.words[i] = 0
        }
    }
}

/*
    get the diffrence between two sets
*/
func (s *IntSet) DiffWith(t *IntSet) {
    for i,_ := range t.words {
        if i < len(s.words) {
            s.words[i] ^= t.words[i]
        }else {
            s.words = append(s.words,t.words[i])
        }
    }
}
/*
    find the symmertic between the two sets
*/
func (s *IntSet) SymDiffWith(t *IntSet) {
    for i,_ := range t.words {
        if i < len(t.words) {
            s.words[i] ^= (s.words[i] & t.words[i])
        }
    }
}
func (s *IntSet) Elems() []uint64 {
    return s.words
}
func main() {
    var x IntSet
    x.AddAll(2,4,5,61)
    fmt.Println(x.String())
    fmt.Println(x.Len())
    x.Remove(5)
    fmt.Println(x.String())
    x.Clear()
    x.Add(100)
    fmt.Println(x.String())
    x.AddAll(1,76,43,23,54)
    var c *IntSet = x.Copy()
    fmt.Println(c.String())
    x.Clear()
    c.Clear()
    x.AddAll(1,45,6,78,98,5,14)
    c.AddAll(6,3,78,12,14)
    x.AndWith(c)
    fmt.Println(x.String())
    x.Clear()
    c.Clear()
    x.AddAll(1,56,3,98,12,53)
    c.AddAll(2,34,56,12,98,3,67)
    x.DiffWith(c)
    fmt.Println(x.String())
    x.Clear()
    c.Clear()
    x.AddAll(1,45,78,9,5,26)
    c.AddAll(23,59,8,9,5,26,32)
    x.SymDiffWith(c)
    fmt.Println(x.String())
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值