2009-12-06 7 views
5

क्या सी #सी # में लुक-अप तालिका करने के लिए सबसे कारगर तरीका क्या है

में लुक-अप तालिका करने के लिए सबसे कारगर तरीका मैं एक लुक-अप तालिका है। की क्रमबद्ध

0 "Thing 1" 
1 "Thing 2" 
2 "Reserved" 
3 "Reserved" 
4 "Reserved" 
5 "Not a Thing" 

इसलिए यदि कोई चाहता है की तरह "बात 1" या "बात 2" वे 0 या 1 में पारित लेकिन वे कुछ में और भी पास कर सकते हैं। मेरे पास 256 प्रकार की चीजें हैं और उनमें से 200 आरक्षित हैं।

तो इसे स्थापित करने के लिए सबसे कुशल क्या है?

  • एक स्ट्रिंग ऐरे या डिक्शनरी वेरिएबल जो सभी मान प्राप्त करता है। और फिर पूर्णांक लें और उस स्थान पर मान वापस करें।

मेरे पास इस समाधान के साथ एक समस्या है "सुरक्षित" मान। मैं उन अनावश्यक "आरक्षित" मानों को नहीं बनाना चाहता हूं। अन्यथा मेरे पास "आरक्षित" सभी विभिन्न स्थानों के खिलाफ एक बयान हो सकता है लेकिन वे अब 2-3 हो सकते हैं, 2-3, 40-55 और बाइट में सभी अलग-अलग जगह हो सकते हैं। यह अगर कथन जल्दी से

  • मेरा दूसरा विकल्प जो मैं सोच रहा था वह एक स्विच स्टेटमेंट था। और मेरे पास 50 के सभी ज्ञात मूल्य होंगे और आरक्षित मूल्यों के माध्यम से और डिफ़ॉल्ट रूप से गिरेंगे।

मुझे आश्चर्य है कि यह एक स्ट्रिंग सरणी या शब्दकोश बनाने और बस उचित मूल्य लौटने से कहीं अधिक प्रसंस्करण है।

  • कुछ और? क्या विचार करने का कोई और तरीका है?
+0

आप जो करना चाहते हैं उसमें प्रदर्शन अंतर महत्वपूर्ण क्यों है? – Paco

उत्तर

10

var things = new Dictionary<int, string>(); 
things[0]="Thing 1"; 
things[1]="Thing 2"; 
things[4711]="Carmen Sandiego"; 
+4

ओ (1) का मतलब यह नहीं है कि कुछ तेज है। इसका मतलब है कि निष्पादन समय स्थिर है। एक ओ (एन) एल्गोरिदम अच्छी तरह से तेज हो सकता है। यह एक आम धारणा है। – 0b101010

+1

लेकिन यह शर्त लगाने का तरीका नहीं है। फिर भी, यदि प्रदर्शन महत्वपूर्ण है तो अपने सटीक परिदृश्य का परीक्षण करें। – PRMan

3

आप सुरक्षित (वर्तमान में अप्रयुक्त) मान के बहुत सारे है या पूर्णांक मानों की श्रेणी बहुत बड़ी प्राप्त कर सकते हैं, तो मैं एक सामान्य शब्दकोश (शब्दकोश) का प्रयोग करेंगे, तो:

var myDictionary = new Dictionary<int, string>(); 
myDictionary.Add(0, "Value 1"); 
myDictionary.Add(200, "Another value"); 
// and so on 

अन्यथा, यदि आप मूल्यों की एक निश्चित संख्या है और के केवल कुछ ही वर्तमान में अप्रयुक्त हैं, तो मैं एक स्ट्रिंग सरणी (स्ट्रिंग [200]) का उपयोग करें और सेट/था आरक्षित प्रविष्टियों छोड़ शून्य पर।

var myArray = new string[200]; 
myArray[0] = "Value 1"; 
myArray[2] = "Another value"; 
//myArray[1] is null 
0

इन-बनाया Dictionary वस्तु (अधिमानतः एक सामान्य शब्दकोश) इस के लिए आदर्श होगा, और विशेष रूप से कुंजी से संबंधित मूल्यों की तेजी/कुशल पुनः प्राप्ति के लिए बनाया गया है।

जुड़ा हुआ MSDN लेख से:

इसकी कुंजी का उपयोग करके एक मूल्य प्राप्त कर रहा है बहुत तेजी से, हे (1) के करीब है, है क्योंकि शब्दकोश < (के < (TKey, TValue>)>) कक्षा को हैश तालिका के रूप में लागू किया गया है।

जहां तक ​​आपकी "आरक्षित" कुंजी जाती है, मैं इसके बारे में चिंता नहीं करता अगर हम केवल कुछ सौ कुंजी/मूल्यों के बारे में बात कर रहे हों। यह तभी होता है जब आप दसियों तक पहुंच जाते हैं, शायद सैकड़ों हजारों "आरक्षित" कुंजी/मान जिन्हें आप कुछ अधिक कुशल बनाना चाहते हैं।

उन मामलों में, शायद सबसे कुशल भंडारण कंटेनर Sparse Matrix का कार्यान्वयन होगा।

0

मुझे पूरा यकीन नहीं है कि मैं आपकी समस्या को सही ढंग से समझता हूं। आपके पास स्ट्रिंग का संग्रह है। प्रत्येक स्ट्रिंग एक सूचकांक से जुड़ा हुआ है। उपभोक्ता अनुरोध एक सूचकांक देता है और आप इसी स्ट्रिंग को वापस करते हैं, जब तक कि सूचकांक आरक्षित सुरक्षित न हो। सही?

क्या आप आरक्षित वस्तुओं को सरणी में शून्य के रूप में सेट नहीं कर सकते हैं।

यदि नहीं, तो ऐसे शब्दकोश का उपयोग करके जिसमें आरक्षित आइटम नहीं हैं, एक उचित समाधान लगता है।

वैसे भी, यदि आप अपनी समस्या को स्पष्ट करते हैं तो आपको शायद बेहतर उत्तर मिलेंगे।

0

लोड आपके सभी

var dic = new Dictionary<int, string>(); 

में मूल्यों और पुनः प्राप्ति के लिए इस का उपयोग करें:

string GetDescription(int val) 
{ 
    if(0 <= val && val < 256) 
     if(!dic.Contains(val)) 
      return "Reserved"; 
     return dic[val]; 
    throw new ApplicationException("Value must be between 0 and 255"); 
} 
+0

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

0

मैं एक शब्दकोश का उपयोग लुकअप करने के लिए होगा। दूर तक देखने के लिए यह सबसे प्रभावी तरीका है। ऑब्जेक्ट खोजने के लिए स्ट्रिंग का उपयोग ओ (एन) के क्षेत्र में कहीं भी चलाया जाएगा।

यह अगर इसकी जरूरत

2

चेकआउट HybridDictionary एक रिवर्स लुकअप करने के लिए आप सभी के लिए एक 2 शब्दकोश के लिए उपयोगी हो सकता है। यह सबसे बड़ी दक्षता प्राप्त करने के लिए आकार के आधार पर स्वचालित रूप से अंतर्निहित स्टोरेज तंत्र को समायोजित करता है।

http://msdn.microsoft.com/en-us/library/system.collections.specialized.hybriddictionary.aspx

+0

हाइब्रिड डिक्शनरी दृढ़ता से टाइप/जेनेरिक नहीं है (संग्रह में सब कुछ एक वस्तु के रूप में संग्रहीत किया जाता है), जिसके परिणामस्वरूप बहुत सारे प्रकार का कास्टिंग हो सकता है (जब तक कि आप इसके चारों ओर एक रैपर नहीं बनाते)। – M4N

+0

बहुत अच्छी कक्षा मुझे नहीं पता था। एमएसडीएन का कहना है कि "उन मामलों के लिए कक्षा की सिफारिश की जाती है जहां एक शब्दकोश में तत्वों की संख्या अज्ञात है।" ऐसा लगता है कि मेस्ट्रो 1024 तत्वों की संख्या जानता है, इसलिए मुझे लगता है कि मेस्ट्रो 1024 को हैशटेबल और लिस्ट डिक्शनरी के बीच चुनना चाहिए। – Eddie

3

निरपेक्ष सबसे तेजी से सी # में पूर्णांक मूल्यों की खोज के ऐसा करने के लिए जिस तरह से एक सरणी के साथ है। एक शब्दकोश का उपयोग करना बेहतर होगा, शायद, यदि आप एक समय में हजारों लुकअप करने की कोशिश कर रहे हैं। ज्यादातर उद्देश्यों के लिए, यह अधिक है; यह अधिक संभावना है कि आपको प्रोसेसर समय की तुलना में डेवलपर समय को अनुकूलित करने की आवश्यकता है।

यदि आरक्षित कुंजी केवल उन सभी कुंजियां नहीं हैं जो लुकअप टेबल में नहीं हैं (यानी यदि कुंजी के लिए लुकअप पाया गया मान, कोई ज्ञात स्थिति या आरक्षित स्थिति नहीं लौटा सकता है), तो आप कहीं आरक्षित कुंजी को बचाने की जरूरत है। उन्हें जादू मानों के साथ शब्दकोश प्रविष्टियों के रूप में सहेजना (उदा। किसी भी शब्दकोश प्रविष्टि की कुंजी जिसका मूल्य शून्य है आरक्षित है) ठीक है जब तक कि आप कोड को लिखने के बिना शब्दकोश की प्रविष्टियों पर पुनरावृत्ति करते हैं।

public class LookupTable 
{ 
    public readonly Dictionary<int, string> Table { get; } 
    public readonly HashSet<int> ReservedKeys { get; } 

    public LookupTable() 
    { 
     Table = new Dictionary<int, string>(); 
     ReservedKeys = new HashSet<int>(); 
    } 

    public string Lookup(int key) 
    { 
     return (ReservedKeys.Contains(key)) 
     ? null 
     : Table[key]; 
    } 
} 

आप यह अभी भी है कि ध्यान दें होगी:

कि समस्या को हल करने के लिए एक तरह से एक अलग HashSet<int> उपयोग करने के लिए सुरक्षित चाबियाँ स्टोर करने के लिए, और शायद एक वर्ग में पूरी बात बेक, जैसे है जादू-मूल्य समस्या - Lookup कुंजी आरक्षित होने पर शून्य वापस आती है, और तालिका में नहीं होने पर अपवाद फेंकता है - लेकिन कम से कम अब आप Table.Values पर जादू मूल्यों को फ़िल्टर किए बिना पुन: सक्रिय कर सकते हैं।

0

आपका प्रश्न यह इंगित करता है कि क्वेरी कुंजी एक पूर्णांक है। चूंकि आपके पास 256 आइटम हैं, तो क्वेरी कुंजी 0.255 की सीमा में है, है ना? यदि ऐसा है, तो बस 256 तारों की एक स्ट्रिंग सरणी है, और सरणी में एक अनुक्रमणिका के रूप में कुंजी का उपयोग करें।

यदि आपकी क्वेरी कुंजी एक स्ट्रिंग मान है, तो यह वास्तविक लुकअप टेबल की तरह है। एक डिक्शनरी ऑब्जेक्ट का उपयोग करना सरल है, लेकिन यदि आप 50 या उससे अधिक वास्तविक उत्तरों के सेट के लिए कच्ची गति के बाद हैं, तो बाइनरी सर्च, या ट्राई जैसे स्वयं के दृष्टिकोण, तेज़ी से हो सकते हैं। यदि आप बाइनरी खोज का उपयोग करते हैं, क्योंकि आइटम की संख्या इतनी छोटी है, तो आप इसे अनलॉक कर सकते हैं।

वस्तुओं की सूची कितनी बार बदलती है? यदि यह केवल बहुत ही कम हो जाता है, तो आप खोज करने के लिए कोड उत्पन्न करके भी बेहतर गति प्राप्त कर सकते हैं, जिसे आप संकलित कर सकते हैं और प्रत्येक क्वेरी करने के लिए निष्पादित कर सकते हैं।

दूसरी ओर, मुझे लगता है कि आप साबित कर चुके हैं कि यह लुकअप आपकी बाधा है, या तो प्रोफाइलिंग या taking stackshots द्वारा। यदि इस क्वेरी में धीमी गति से 10% से कम समय बिताया जाता है, तो यह आपकी बाधा नहीं है ताकि आप कोड के लिए सबसे आसान चीज भी कर सकें।

संबंधित मुद्दे