मुझे वास्तव में Google गोलगप्पा पसंद है, लेकिन क्या कोई समझा सकता है कि कार्यान्वयनकर्ताओं के लिए तर्क क्या है जो मानक पुस्तकालय से सेट के रूप में एक बुनियादी डेटा संरचना को छोड़ दिया है?
मुझे वास्तव में Google गोलगप्पा पसंद है, लेकिन क्या कोई समझा सकता है कि कार्यान्वयनकर्ताओं के लिए तर्क क्या है जो मानक पुस्तकालय से सेट के रूप में एक बुनियादी डेटा संरचना को छोड़ दिया है?
जवाबों:
इस चूक का एक संभावित कारण यह है कि नक्शे के साथ मॉडल सेट करना वास्तव में आसान है।
सच कहूं तो मुझे लगता है कि यह थोड़ा बहुत है, लेकिन पर्ल की कहानी भी बिल्कुल वैसी ही है। पर्ल में आपको लिस्ट और हैशटेबल्स मिलते हैं, गो में आपको एरेज़, स्लाइस और मैप्स मिलते हैं। पर्ल में आप आम तौर पर सेट से संबंधित किसी भी और सभी समस्याओं के लिए एक हैशटेबल का उपयोग करेंगे, वही गो पर लागू होता है।
उदाहरण
जाओ में एक सेट ints की नकल करने के लिए, हम एक नक्शे को परिभाषित करते हैं:
set := make(map[int]bool)
कुछ जोड़ने के लिए के रूप में आसान है:
i := valueToAdd()
set[i] = true
कुछ हटाना बस है
delete(set, i)
और इस निर्माण की संभावित अजीबता आसानी से दूर हो गई है:
type IntSet struct {
set map[int]bool
}
func (set *IntSet) Add(i int) bool {
_, found := set.set[i]
set.set[i] = true
return !found //False if it existed already
}
और डिलीट एंड गेट को इसी तरह परिभाषित किया जा सकता है, मेरा यहां पूरा कार्यान्वयन है । यहाँ प्रमुख असन्तुलन यह तथ्य है कि गो में जेनरिक नहीं है। हालाँकि यह संभव है कि interface{}
आप किस स्थिति में परिणाम प्राप्त करना चाहते हैं।
map[int]bool
एक का उपयोग कर सकते हैं map[int]struct{}
। मैं आखिरी पसंद करता हूं।
map[int]struct{}
.. struct{}
0 बाइट लेता है।
map[int]struct{}
आप ऐसा नहीं कर सकते if mymap["key"] {
सदस्यता के लिए जाँच करने के लिए। Google का उपयोग करने की अनुशंसा करता हैbool
("एक सेट लागू किया जा सकता है" के लिए खोज)।
मुझे लगता है कि यह golang
सादगी पर ध्यान केंद्रित करना है । set
साथ वास्तव में उपयोगी बन रहा है difference
, intersection
, union
, issubset
, और इतने पर .. तरीकों। शायद golang
टीम ने महसूस किया कि यह एक डेटा संरचना के लिए बहुत अधिक है। लेकिन अन्यथा एक "गूंगा सेट" जो केवल है add
, contains
और remove
आसानी map
से @jozefg द्वारा समझाया जा सकता है ।
पिछला उत्तर केवल कार्य करता है यदि कुंजी एक अंतर्निहित प्रकार है। पिछले उत्तर के पूरक के लिए, यहां एक सेट लागू करने का एक तरीका है जिसके तत्व उपयोगकर्ता-परिभाषित प्रकार हैं:
package math
// types
type IntPoint struct {
X, Y int
}
// set implementation for small number of items
type IntPointSet struct {
slice []IntPoint
}
// functions
func (p1 IntPoint) Equals(p2 IntPoint) bool {
return (p1.X == p2.X) && (p1.Y == p2.Y)
}
func (set *IntPointSet) Add(p IntPoint) {
if ! set.Contains(p) {
set.slice = append(set.slice, p)
}
}
func (set IntPointSet) Contains(p IntPoint) bool {
for _, v := range set.slice {
if v.Equals(p) {
return true
}
}
return false
}
func (set IntPointSet) NumElements() int {
return len(set.slice)
}
func NewIntPointSet() IntPointSet {
return IntPointSet{(make([]IntPoint, 0, 10))}
}
type mySet map[IntPoint]bool
पूरी तरह से अच्छी तरह से काम करता है। एक मानचित्र में उपयोग किए जाने वाले कुंजी प्रकार की आवश्यकता होती है, वह यह==
!=
है कि यह है और । संरचना प्रकार की समानता को अच्छी तरह से परिभाषित किया गया है, आपकी Equals
विधि बस होनी चाहिए p1 == p2
।
Contains
लेता हूं, क्योंकि aMap[]
सदस्यों की संख्या की परवाह किए बिना , रैखिक समय लगता है , जबकि निरंतर समय लगता है। एक बेहतर समाधान आंतरिक रूप से प्रत्येक सदस्य की सामग्री के आधार पर एक अद्वितीय कुंजी तैयार करेगा, और इस map
प्रकार प्रदान करने वाले निरंतर-समय क्वेरी का लाभ उठाएगा । यहां तक कि तेजी से समाधान जो कैश व्यवहार पर विचार करते हैं, आदि भी मौजूद हैं।