C # शब्दकोशों की क्षमता


14

C # शब्दकोष एक सरल तरीका है जिससे यह पता लगाया जा सकता है कि कुछ मौजूद है आदि। मेरा एक प्रश्न है कि वे कैसे काम करते हैं। मान लीजिए कि मैं एक शब्दकोष के बजाय एक ArrayList का उपयोग करता हूं। उपयोग करने के बजाय ContainsKey(या किसी अन्य भाषा में समतुल्य विधि) I यह जाँचने के लिए ArrayList के माध्यम से लूप करता है कि क्या कुछ मौजूद है (या डेटा सॉर्ट करने या कुछ इसी तरह से बाइनरी सर्च करने पर)। दक्षता में क्या अंतर है? क्या ContainsKeyविधि कुंजियों के माध्यम से लूप करने के बजाय कुछ अधिक कुशल तरीके का उपयोग कर रही है और जांचें कि क्या मैं जो खोज रहा हूं वह मौजूद है?

अगर मान लें कि मैंने एक विशिष्ट हैश फ़ंक्शन बनाया है, जो उस डेटा के प्रकार से मेल खाता है जो मेरे पास है और विशेष रूप से डेटा के उस सेट के लिए डिज़ाइन किया गया है, तो हाँ, यह हैश फ़ंक्शन वास्तव में डेटा के माध्यम से लूपिंग से तेज है। लेकिन शब्दकोश सामान्य हैं। ContainsKey विधि उस डेटा के लिए विशिष्ट नहीं है जो इसे मिलती है, यह एक सामान्य खोज विधि है।

मूल रूप से जो मैं पूछ रहा हूं वह है। शब्दकोश प्रोग्रामर के लिए उपयोगी होते हैं। उनमें ऐसी विधियाँ शामिल हैं जो कई चीज़ों की मदद करती हैं और वे पूर्णांक, (कुंजियाँ और मान) और कई और चीज़ों के साथ तार जोड़ती हैं। लेकिन दक्षता के विषय में, वे क्या प्रदान करते हैं? एक dictionaryबनाम के होने में क्या अंतर ArrayListहैstructs(string,int)


आप वास्तव में सेब की तुलना यहां के संतरे से कर रहे हैं। मुझे लगता है कि आप जिस कीवर्ड की तलाश कर रहे हैं, वह Data Structures यह है कि विकी लिंक आपके लिए अधिक मददगार हो सकता है
Ampt

जवाबों:


23

आपको यह देखने के लिए थोड़ी सी खुदाई करनी होगी कि कैसे शब्दकोश को C # में लागू किया गया है - यह HashMap (एक हैश टेबल) या ट्री मैप (एक सॉर्ट किए गए ट्री) (या समवर्तीSkipListMap - एक स्किप सूची ) के रूप में स्पष्ट नहीं है ।

यदि आप "रिमार्क्स" अनुभाग में खोदते हैं:

डिक्शनरी जेनेरिक क्लास कुंजियों के सेट से मानों के एक सेट तक मानचित्रण प्रदान करता है। शब्दकोश में प्रत्येक जोड़ में एक मूल्य और उससे जुड़ी कुंजी होती है। इसकी कुंजी का उपयोग करके किसी मूल्य को प्राप्त करना बहुत तेज़ है, O (1) के करीब है, क्योंकि शब्दकोश वर्ग एक हैश तालिका के रूप में कार्यान्वित किया जाता है।

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

जबकि डिक्शनरी एक सामान्य उद्देश्य समाधान है जिसे आपको ठोस प्रकारों (जैसे कि डिक्शनरी) के आस-पास से गुजरना नहीं चाहिए - आपको इंटरफेस के आसपास से गुजरना चाहिए। इस स्थिति में, वह इंटरफ़ेस IDictionary( डॉक्स ) है। इसके लिए, आप अपने खुद के शब्दकोश कार्यान्वयन को लिखने में पूरी तरह से सक्षम हैं जो आपके पास मौजूद डेटा के लिए बेहतर तरीके से काम करता है।

विभिन्न लुकअप की दक्षता / सम्‍मिलित है?

  • एक अनसुलझी सूची चलना: O (N)
  • एक क्रमबद्ध सरणी की बाइनरी खोज: O (लॉग एन)
  • सॉर्ट किया गया पेड़: O (लॉग एन)
  • हैश टेबल: ओ (1)

अधिकांश लोगों के लिए, हैश तालिका वे चाहते हैं।

आप पा सकते हैं कि SortedDictionary है जो आप के बजाय चाहते हैं:

SortedDictionary<TKey, TValue>सामान्य वर्ग हे (लॉग एन) पुनः प्राप्ति, जहां n शब्दकोश में तत्वों की संख्या है के साथ एक द्विआधारी खोज वृक्ष है। इस संबंध में, यह SortedList<TKey, TValue>सामान्य वर्ग के समान है । दो वर्गों में समान ऑब्जेक्ट मॉडल हैं, और दोनों में ओ (लॉग एन) पुनर्प्राप्ति है।

हालाँकि, फिर से, यदि डेटा संरचना एक नहीं है जो आपके डेटा के साथ आदर्श रूप से काम करता है, तो आपको उपकरण (इंटरफेस) दिए गए हैं जो आपके डेटा के लिए सबसे अच्छा काम करने में सक्षम हो।

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


5
ओ (1) जरूरी "तेज" नहीं है। एक सूची के माध्यम से लूपिंग अभी भी संग्रह के आकार के लिए एक हैशटेबल की तुलना में तेज हो सकता है, जो अनुप्रयोग के साथ काम कर रहा है।
whatsisname

5
@whatsisname बिना किसी बिंदु के मेरा दावा है कि O (1) तेज है। यह निश्चित रूप से सबसे तेज होने की क्षमता है। हैशटेब की चाबियों पर फेरबदल एक ArrayList की तुलना में धीमा है (जब तक कि आप LinkedHashMap की तरह कुछ का उपयोग नहीं कर रहे हैं जो जावा प्रदान करता है)। अपने डेटा को जानना महत्वपूर्ण है और यह कैसे व्यवहार करता है और इसके लिए उपयुक्त संग्रह को चुना - और यदि वह मौजूद नहीं है, तो इसे लिखें। यह मानते हुए कि इस तरह का प्रयास वास्तव में समय के लायक है (प्रोफ़ाइल पहले!)।

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

3
@whatsisname जो Microsoft से प्रत्यक्ष है। एक मूल्य को देखने के लिए एक कुंजी का उपयोग करना, जब तक कि आपके पास एक पैथोलॉजिकल हैशटेबल (जो कुछ अन्य तंत्र के साथ हैश टकरावों को हल करता है) एक पेड़ या सॉर्ट की गई सूची (या अनसुलझी सूची) में देखने की तुलना में तेज होगा। उदाहरण के लिए, जावा अपने टकराव के समाधान के लिए रैखिक जांच (चरण 1) का उपयोग करता है - जो उन मामलों में धीमा हो सकता है जहां तालिका बहुत भरी हुई है या बहुत अधिक हैश टकराते हैं। सामान्य मामले के लिए, यह काफी अच्छा है।

एक प्रासंगिक उदाहरण के रूप में, मैंने हाल ही में c ++ में कुछ कोड को अनुकूलित किया है जो मूल रूप से लगभग 20 प्रविष्टियों के डेटा सेट के लिए हैश टेबल का उपयोग कर रहा था और पूरा होने में लगभग 400ms ले रहा था। एक बाइनरी ट्री पर स्विच करने से वह 200 मी तक नीचे आ गया, क्योंकि पेड़ तक पहुंच आसान है। लेकिन मैं अभी भी नाम मूल्य जोड़े की एक सरणी का उपयोग करके इसे आगे काटने में सक्षम था और एक हेयुरिस्टिक लुक फंक्शन था जो अनुमान लगाता था कि पिछले एक्सेस पैटर्न के आधार पर कहां देखना शुरू करना है। तो यह सब एक बात है कि एक्सेस में कितना डेटा है और किस तरह का पैटर्न है (जैसे स्थानीयता)।
जूल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.