2012-11-22 22 views
15

में एक निश्चित मान है या नहीं, यह जांचने का सबसे अच्छा तरीका क्या है कि एक निश्चित मान स्ट्रिंग स्लाइस में है या नहीं? मैं अन्य भाषाओं में एक सेट का उपयोग करता हूं, लेकिन गो में कोई नहीं है।जांचें कि क्या स्ट्रिंग स्लाइस में गो

पूरी कोशिश यह अब तक है:

package main 

import "fmt" 

func main() { 
    list := []string{"a", "b", "x"} 
    fmt.Println(isValueInList("b", list)) 
    fmt.Println(isValueInList("z", list)) 
} 

func isValueInList(value string, list []string) bool { 
    for _, v := range list { 
     if v == value { 
      return true 
     } 
    } 
    return false 
} 

http://play.golang.org/p/gkwMz5j09n

यह समाधान छोटे स्लाइस के लिए ठीक होना चाहिए, लेकिन क्या कई तत्वों के साथ स्लाइस के लिए करना है?

उत्तर

37

आप एक मनमाना क्रम में तार का एक टुकड़ा है, लग रहा है, तो एक मूल्य के मौजूद है, तो में टुकड़ा हे की आवश्यकता है (एन) समय। यह सभी भाषाओं पर लागू होता है।

यदि आप बार-बार एक खोज करना चाहते हैं, तो आप लुकअप को तेज़ी से बनाने के लिए अन्य डेटा संरचनाओं का उपयोग कर सकते हैं। हालांकि, इन संरचनाओं के निर्माण के लिए कम से कम ओ (एन) समय की आवश्यकता होती है। इसलिए यदि आप एक बार से अधिक डेटा संरचना का उपयोग कर लुकअप करते हैं तो आपको केवल लाभ मिलेगा।

उदाहरण के लिए, आप अपने तारों को मानचित्र में लोड कर सकते हैं। फिर लुकअप ओ (1) समय लेगा।

set := make(map[string]bool) 
for _, v := range list { 
    set[v] = true 
} 

fmt.Println(set["b"]) 

तुम भी तरह अपने स्ट्रिंग टुकड़ा और फिर एक द्विआधारी खोज कर सकते हैं: निवेशन भी हे (1) समय प्रारंभिक निर्माण ले हे (एन) समय बनाने लेते हैं। बाइनरी खोज ओ (लॉग (एन)) समय में होती है। बिल्डिंग ओ (एन * लॉग (एन)) समय ले सकता है।

sort.Strings(list) 
i := sort.SearchStrings(list, "b") 
fmt.Println(i < len(list) && list[i] == "b") 

सिद्धांत में मूल्यों की एक अनंत संख्या को देखते हुए हालांकि, एक नक्शा तेजी से, व्यवहार में तो बहुत संभव है खोज कर रहा है एक हल कर सूची तेजी से हो जाएगा। आपको इसे स्वयं बेंचमार्क करना होगा।

4

सेट्स को प्रतिस्थापित करने के लिए आप map[string]whatever का उपयोग कर सकते हैं। यह हल्का नहीं होगा जिसे आप कल्पना कर सकते हैं (उस मूल्य के लिए एक सूचक है जिसकी आपको आवश्यकता नहीं है) लेकिन अपनी खुद की हैश तालिका लिखने के अलावा यह सबसे कुशल है, और यह बहुत ही अनुकूलित है क्योंकि यह अंतर्निहित है। अगर एक आइटम मौजूद है

set[item]=1 

जांच करने के लिए:

_, ok = set[item] 

यह जाओ में एक आम मुहावरा है

set := make(map[string]uint8) 

एक आइटम कहें। यदि ठीक है, तो आइटम मौजूद था। यदि ठीक है तो गलत है, तो आइटम मौजूद नहीं था।

+6

बेवकूफ गो के लिए आप या तो 'नक्शा [कीट टाइप] संरचना {} '(मूल्य के रूप में एक खाली शून्य आकार की संरचना) या' मानचित्र [कीटाइप] बूल 'का उपयोग करेंगे और ** ** ** ** जैसा दिखाया गया है। पूर्व के लिए आप '_, ठीक: = सेट [आइटम] 'निर्माण का उपयोग करेंगे। यदि बूल का उपयोग करना है तो आप केवल 'आइटम [सेट] सेट कर सकते हैं क्योंकि गैर-मौजूद प्रविष्टियां ["शून्य मान"] (https://golang.org/ref/spec#The_zero_value) लौटाती हैं, जो बूल के लिए गलत है। –

2

आप मानचित्र का उपयोग कर सकते हैं, और मूल्य का उपयोग कर सकते हैं। एक bool

m := map[string] bool {"a":true, "b":true, "x":true} 
if m["a"] { // will be false if "a" is not in the map 
    //it was in the map 
} 

वहाँ भी sort पैकेज है, तो आप क्रमबद्ध सकता है और द्विआधारी खोज अपने स्लाइस

+2

ध्यान दें कि आपको बूल डमी मानों का उपयोग करने की आवश्यकता नहीं है। आप इस तरह एक खाली संरचना का उपयोग कर सकते हैं: 'नक्शा [स्ट्रिंग] संरचना {} '। – nemo

+3

बस यह स्पष्ट करने के लिए कि @nemo ने कहा, संरचना {} का उपयोग करने का लाभ यह है कि इसमें कोई स्मृति नहीं है। –

+2

"इसमें कोई स्मृति नहीं है" ... मूल्यों के लिए, निश्चित रूप से नक्शा अभी भी चाबियाँ और हैश तालिका (या जो भी कार्यान्वयन) के लिए स्मृति लेता है, यह मानचित्र द्वारा उपयोग की जाने वाली स्मृति को कम करता है ('_ _ , ठीक है: = नक्शा ["ए"]; ठीक है 'स्टाइल चेक सिर्फ' अगर नक्शा ["ए"] ')। –