簡體   English   中英

如何用Go實現BitSet?

[英]How to implement BitSet with Go?

我沒有在Go中找到BitSet包,所以我嘗試實現它。 我想使用uint64數組來存儲這些位。

我需要分配uint64數組的位數。 使用Java,我可以定義一個帶整數的構造函數。 雖然Go不提供構造函數,但是當用戶調用new()時如何正確初始化BitSet'對象'?

如果使用[] uint64切片來存儲數據,則零切片可以用作空BitSet。 事實上,附加到nil切片會為您分配一個新數組,盡管語言規范似乎並不能保證這一點。 通過這種設置,新的(BitSet)可以立即使用。 例:

bitset.go:

package bitset

const size = 64

type bits uint64

// BitSet is a set of bits that can be set, cleared and queried.
type BitSet []bits

// Set ensures that the given bit is set in the BitSet.
func (s *BitSet) Set(i uint) {
    if len(*s) < int(i/size+1) {
        r := make([]bits, i/size+1)
        copy(r, *s)
        *s = r
    }
    (*s)[i/size] |= 1 << (i % size)
}

// Clear ensures that the given bit is cleared (not set) in the BitSet.
func (s *BitSet) Clear(i uint) {
    if len(*s) >= int(i/size+1) {
        (*s)[i/size] &^= 1 << (i % size)
    }
}

// IsSet returns true if the given bit is set, false if it is cleared.
func (s *BitSet) IsSet(i uint) bool {
    return (*s)[i/size]&(1<<(i%size)) != 0
}

bitset_test.go:

package bitset

import "fmt"

func ExampleBitSet() {
    s := new(BitSet)
    s.Set(13)
    s.Set(45)
    s.Clear(13)
    fmt.Printf("s.IsSet(13) = %t; s.IsSet(45) = %t; s.IsSet(30) = %t\n",
               s.IsSet(13), s.IsSet(45), s.IsSet(30))
    // Output: s.IsSet(13) = false; s.IsSet(45) = true; s.IsSet(30) = false
}

將bitSet聲明為私有結構:

type bitSet struct {
  len int
  array []uint64
}

公開接口BitSet:

type BitSet interface {
  Has(pos int) bool
  Add(pos int) bool
  Len() int
}

還公開一個函數NewBitSet:

func NewBitSet(len int) BitSet {
  return &bitSet{len, make(uint64, (len+7) / 8) }
}

這是封裝的Go方式:共享接口,而不是實現。

簡短的回答是,當客戶端調用new ()時,無法正確初始化BitSet對象。

你可以做的最好的事情是使你的BitSet的零值有效。 這就是list.Listsync.Mutexbig.Int這樣的類型。 這樣您就知道客戶端無法獲得無效值。

您可以做的下一件事是創建類似於NewBitSet函數(在本例中名為NewBitSet )並期望客戶端調用它。

Go的標准big.Int可以用作位集:

package main

import (
    "fmt"
    "math/big"
)

func main() {
    var bits big.Int
    for i := 1000; i < 2000; i++ {
        bits.SetBit(&bits, i, 1)
    }
    for i := 0; i < 10000; i++ {
        if bits.Bit(i) != 0 {
            fmt.Println(i)
        }
    }
}

https://play.golang.org/p/xbIK-boouqC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM