2010-02-22 12 views
10

मुझे गो में बिटसेट पैकेज नहीं मिला, इसलिए मैंने इसे लागू करने का प्रयास किया। मैं बिट्स को स्टोर करने के लिए uint64 की एक सरणी का उपयोग करना चाहता हूं।बिट के साथ बिटसेट को कैसे कार्यान्वित करें?

मुझे uint64 सरणी आवंटित करने के लिए बिट्स की संख्या की आवश्यकता है। जावा के साथ, मैं एक कन्स्ट्रक्टर को परिभाषित कर सकता हूं जो पूर्णांक लेता है। जबकि गो कन्स्ट्रक्टर प्रदान नहीं करता है, जबकि उपयोगकर्ता बिटसेट 'ऑब्जेक्ट' को सही ढंग से कैसे प्रारंभ कर सकता है जब उपयोगकर्ता नया() कहता है?

उत्तर

3

bitSet एक निजी struct के रूप में घोषित करें:

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) } 
} 

यह कैप्सूलीकरण के लिए एक जाओ तरीका है

type bitSet struct { 
    len int 
    array []uint64 
} 

इंटरफ़ेस BitSet बेनकाब : एक इंटरफ़ेस साझा करें, कार्यान्वयन नहीं।

+2

मैं इस समाधान से पूरी तरह से सहमत नहीं हूं। मुझे लगता है कि एक बिटसेट एक इंटरफ़ेस होने के लिए बहुत विशिष्ट है।यह आपको अलग-अलग बिट्ससेट्स की अनुमति देता है जो एक ही इंटरफ़ेस को लागू करते हैं, लेकिन क्या आपको वास्तव में ऐसी चीज़ की आवश्यकता है? ऐसा लगता है कि आप शायद एक बिटसेट कार्यान्वयन के साथ आ सकते हैं जो कि किसी भी उपयोग के लिए अच्छी तरह से काम करेगा और हमेशा इसका उपयोग करें। कई कार्यान्वयन संभवतः लोगों को भ्रमित कर देगा। –

+0

जब आपको किसी अन्य कार्यान्वयन की आवश्यकता होती है तो बहुत सारे मामले होते हैं: बड़ी अतिरिक्त बिटसेट, वितरित/लेनदेन संबंधी बिटसेट, वर्चुअल बिटसेट (कुछ सेटिंग को साफ़ करना/साफ़ करना) और इसी तरह। –

+0

मुझे लगता है कि गो में ऑब्जेक्ट प्रारंभ करने के लिए कोई समान तरीका नहीं है। :( नया (बिटसेट), बिटसेट .New(), न्यूबिटसेट(), ... वे कैसे संबंधित हैं? –

1

संक्षिप्त उत्तर यह है कि जब आप new() पर कॉल करते हैं तो आप BitSet ऑब्जेक्ट को ठीक से प्रारंभ नहीं कर सकते हैं।

सबसे अच्छी बात यह है कि आप इसे कर सकते हैं ताकि आपका BitSet का शून्य मान मान्य हो। यह list.List, sync.Mutex, और big.Int जैसे प्रकार हैं। इस तरह आप जानते हैं कि क्लाइंट के लिए अमान्य मान प्राप्त करना असंभव है।

अगली सबसे अच्छी बात यह है कि आप एक कंसक्टर-जैसी फ़ंक्शन (इस मामले में NewBitSet नामित) बना सकते हैं और ग्राहकों को इसे कॉल करने की उम्मीद करते हैं।

+0

तब मैं List.New() और नहीं नई (सूची) कॉल कर सकते हैं? एक नए पैकेज के लिए, मैं कैसे जान सकता हूं कि एक नई वस्तु कैसे बनाएं? –

+0

मुझे लगता है कि यह सही है, हालांकि मुझे गलत याद आ रहा है। आप नई (सूची) को कॉल नहीं करना चाहेंगे, भले ही इसकी अनुमति हो, क्योंकि आप ऑब्जेक्ट को सही तरीके से प्रारंभ नहीं कर पाएंगे। आप एक नई वस्तु को कैसे बना सकते हैं, यह पता लगा सकते हैं कि पैकेज के भीतर कुछ और कैसे करना है: दस्तावेज़ पढ़ें। आम तौर पर इन कन्स्ट्रक्टर-जैसे कार्यों में कम से कम उनमें "नया" शब्द होगा। –

+0

यह पता चला है कि आप बिना किसी निर्यात किए गए फ़ील्ड के साथ ऑब्जेक्ट बना सकते हैं()। यह बहुत उपयोगी प्रतीत नहीं होता है, जब तक उस ऑब्जेक्ट में किसी प्रकार का प्रारंभिक कार्य नहीं होता है जिसे आप कॉल कर सकते हैं। –

3

यदि आप अपने डेटा को स्टोर करने के लिए [] uint64 टुकड़ा का उपयोग करते हैं, तो शून्य टुकड़ा खाली बिटसेट के रूप में कार्य कर सकता है। असल में एक नील स्लाइस में शामिल होने से आपके लिए एक नई सरणी आवंटित होती है, हालांकि भाषा विशिष्टता उस गारंटी की प्रतीत नहीं होती है। उस तरह के सेटअप के साथ, नया (बिटसेट) तत्काल उपयोग योग्य होगा। उदाहरण:

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 
} 
संबंधित मुद्दे