2010-01-27 17 views
17

के लिए मानों की श्रृंखला का उपयोग करती है मुझे एक विशेष शब्दकोश की आवश्यकता है। मेरा उपयोग मामला यह है: उपयोगकर्ता मानों की श्रेणियां निर्दिष्ट करना चाहता है (सीमा भी एक बिंदु हो सकती है) और किसी विशेष सीमा के लिए मान असाइन करें। फिर हम एक कुंजी के रूप में एक एकल मान का उपयोग करके एक लुकअप करना चाहते हैं। यदि यह एकल मान किसी श्रेणी के भीतर होता है तो हम सीमा से जुड़े मूल्य को वापस कर देंगे।एक शब्दकोश वस्तु जो कुंजी

उदाहरण के लिए:

// represents the keyed value 
struct Interval 
{ 
    public int Min; 
    public int Max; 
} 

// some code elsewhere in the program 
var dictionary = new Dictionary<Interval, double>(); 
dictionary.Add(new Interval { Min = 0, Max = 10 }, 9.0); 
var result = dictionary[1]; 
if (result == 9.0) JumpForJoy(); 

यह स्पष्ट रूप से सिर्फ मैं क्या देख रहा हूँ वर्णन करने के लिए कुछ कोड है। क्या किसी को ऐसी चीज को लागू करने के लिए एल्गोरिदम के बारे में पता है? यदि ऐसा है तो वे मुझे इसके प्रति इंगित कर सकते हैं, कृपया?

मैंने पहले से ही एक कस्टम IEqualityComparer ऑब्जेक्ट को लागू करने और अंतराल पर बराबर() और GetHashCode() को अधिभारित करने का प्रयास किया है लेकिन अब तक इसका कोई फायदा नहीं हुआ है। ऐसा हो सकता है कि मैं कुछ गलत कर रहा हूँ।

+1

आपको अपना खुद का कस्टम संग्रह लागू करना होगा। मुझे नहीं लगता कि आप मानक शब्दकोश वर्ग के साथ क्या मांग रहे हैं। – Nick

+0

चूंकि आपकी अंतराल सीमाएं पूर्णांक हैं, यदि आपका डोमेन पर्याप्त रूप से छोटा है और कोई भी दो अंतराल ओवरलैप नहीं है, तो आप केवल युगल की सरणी का उपयोग कर सकते हैं। आपके उदाहरण में, इंडेक्स 0 से 10 पर सरणी तत्व 9.0 पर सेट किए जाएंगे। लुकअप तब ओ (1) है। –

+0

मैं कहूंगा कि 'बराबर' को ओवरराइड करने से आपको सही परिणाम मिलेंगे, लेकिन इसका मतलब है कि आपके पास – nawfal

उत्तर

24

एक शब्दकोश आपके द्वारा वर्णित संचालन के लिए उचित डेटा संरचना नहीं है।

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

यदि अंतराल ओवरलैप हो सकता है तो आपको हल करने में एक और मुश्किल समस्या है। इस समस्या का समाधान करने के लिए कुशलतापूर्वक आप एक अंतराल पेड़ का निर्माण करना चाहते हैं:

http://en.wikipedia.org/wiki/Interval_tree

यह एक अच्छी तरह से ज्ञात डेटा संरचना है। डेटा संरचनाओं पर "एल्गोरिदम के लिए परिचय" या किसी अन्य सभ्य स्नातक पाठ को देखें।

+0

अंतराल को मेरे सिमुलेशन में ओवरलैप करने की अनुमति नहीं है, इसलिए मैं सॉर्ट किए गए सूची में रहूंगा। सलाह एरिक के लिए धन्यवाद! –

+0

हालांकि जेफरी कैमरून की टिप्पणी काफी पुरानी है, लेकिन इस समय सॉर्टेडलिस्ट के पास निकटतम कुंजी ऑपरेशन नहीं है। इस समय, सूची वर्ग और सूची। बाइनरीशर्च विधि वे हैं जो तेजी से निकटतम कुंजी लुकअप प्रदान कर सकती हैं। – Cameron

6

यह केवल तब काम करने जा रहा है जब अंतराल ओवरलैप न हो। और आपकी मुख्य समस्या एक एकल (कुंजी) मान से अंतराल में परिवर्तित हो रही है।

मैं सॉर्टेडलिस्ट के चारों ओर एक रैपर लिखूंगा। SortedList.Keys.IndexOf() आपको एक इंडेक्स मिलेगा जिसका उपयोग यह सत्यापित करने के लिए किया जा सकता है कि अंतराल वैध है या नहीं।

+0

शब्दकोश में एक साथ ओवरलैप होने वाली दो कुंजी नहीं हो सकती हैं। मैंने कस्टम तुलनात्मक सूची के साथ एक मानक सॉर्टेडलिस्ट का उपयोग करके इसे अभी कोशिश की है (जो जांचता है देखें कि अंतराल छेड़छाड़ करता है या नहीं। यह अच्छी तरह से काम कर रहा है! –

+4

दरअसल, अगर अंतराल ओवरलैप नहीं होने की आवश्यकता होती है तो समस्या छोटी होती है; आप केवल एक क्रमबद्ध सूची को बाइनरी कर सकते हैं। यदि अंतराल को ओवरलैप करने की अनुमति है तो आपके पास अधिक कठिन समस्या। –

2

यह वही नहीं है जो आप चाहते हैं लेकिन मुझे लगता है कि यह अपेक्षाकृत निकटतम हो सकता है।

आप निश्चित रूप से इससे बेहतर कर सकते हैं (क्या मैं पहले पी रहा था?)। लेकिन आपको यह स्वीकार करना होगा कि यह अच्छा और सरल है।

var map = new Dictionary<Func<double, bool>, double>() 
{ 
    { d => d >= 0.0 && d <= 10.0, 9.0 } 
}; 

var key = map.Keys.Single(test => test(1.0)) 
var value = map[key]; 
+0

दिलचस्प, मैंने एक समारोह के रूप में एक फ़ंक्शन का उपयोग करने के बारे में सोचा नहीं था ...! मेरे उपयोग करने वाले शब्दकोश का बिंदु ओ (1) लुकअप होना था, हालांकि इस तालिका को कई बार पूछताछ की जाएगी। क्या कोई है लुकअप को जल्दी बनाने का तरीका? –

+0

यह ओ (एन) लुकअप में है। आप उससे बेहतर तरीके से कर सकते हैं। –

+2

@Eric - आखिर में शर्मिंदगी के मिश्रणों के लिए गेदर। :) – ChaosPandion

-2

आप powercollections यहाँ codeplex एक संग्रह है कि आप के लिए क्या देख रहे क्या कर सकते हैं नहीं है पर पाया की जाँच कर सकते हैं।

उम्मीद है कि यह मदद करता है, सर्वश्रेष्ठ संबंध, टॉम।

+0

वह संग्रह प्रकार क्या होगा? –

+0

@ जोर्न शू-रोड: मल्टी डिक्शनरी, 'मल्टी डिक्शनरी क्लास जो एक कुंजी के साथ मूल्यों को जोड़ती है। एक शब्दकोश के विपरीत, प्रत्येक कुंजी के साथ जुड़े कई मान हो सकते हैं। किसी कुंजी से जुड़े एक मान के बजाय, मल्टी डिक्शनरी को अनुक्रमणित करते समय, आप मानों की गणना पुनर्प्राप्त करते हैं। ' – t0mm13b

+0

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

1

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

यह कुछ हद तक समस्या को सरल बनाता है। इसके बाद हमने बाइनरी चॉप को लागू करके प्रमुख खोजों को अनुकूलित किया। मैं दुर्भाग्य से कोड साझा नहीं कर सकता।

0

मैं एक छोटे से अंतराल वर्ग, बनाना होगा जो ऐसा ही कुछ होगा:

public class Interval 
{ 
    public int Start {get; set;} 
    public int End {get; set;} 
    public int Step {get; set;} 
    public double Value {get; set;} 

    public WriteToDictionary(Dictionary<int, double> dict) 
    { 
     for(int i = Start; i < End; i += Step) 
     { 
      dict.Add(i, Value); 
     } 
    } 
} 

तो आप अभी भी कर सकते हैं अपने शब्दकोश के भीतर एक सामान्य देखने। शायद आपको Add() पर कॉल करने से पहले कुछ चेक भी करना चाहिए या किसी भी प्रकार का रोलबैक लागू करना चाहिए यदि कोई मान पहले से ही शब्दकोश में है।

0

Open Geospatial Library में आप एक अंतराल पेड़ के Java flavored सी # कार्यान्वयन पा सकते हैं। आपकी समस्या को हल करने के लिए इसे कुछ मामूली बदलावों की आवश्यकता है और यह वास्तव में कुछ सी # -फिकेशन का भी उपयोग कर सकता है।

यह ओपन सोर्स है लेकिन मुझे लाइसेंस के तहत पता नहीं है।

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