2009-08-21 4 views
30

मैं एक प्रयोग मामले में जहां एक संख्या 0-10 के बीच स्थित है, अगर यह 0 लौट जाना है और अगर यह 11-20 के बीच स्थित यह 1 आदिका उपयोग जावा मानचित्र खोज

0 => 0-3, (0 and 3 are inclusive) 
1 => 4-15, (4 and 15 are inclusive) 
2 => 16-40, (16 and 40 are inclusive) 
3 => 41-88, (41 and 88 are inclusive) 
5 => 89-300 (89 and 300 are inclusive) 

लौटना चाहिए मैं सोच रहा था मैं कैसे लागू कर सकते हैं और जावा नक्शे में सोच रहा था, लेकिन यह सीमा खोज

मैं कुछ इस तरह में दिलचस्पी है की अनुमति नहीं है, मैं एक समारोह है

int foo() { 

} 

अगर foo 5 देता है, क्योंकि यह 0 के बीच स्थित है टी ओ 10 मैं 0 का प्रयोग करेंगे, अगर foo वापसी 25 यह 2.

कोई भी विचार

संपादित करें का प्रयोग करेंगे: असल में पर्वतमाला 0-10, 11-20 के रूप में सरल नहीं हैं। मैं रेंज खोज करने में सक्षम होना चाहता हूँ। भ्रम के बारे में खेद है। प्रश्नों के आधार पर मैंने सही उदाहरण जोड़ा है, संख्याएं

+0

प्रदान करें की जरूरत है आप जो करना चाहते हैं उसका वास्तविक उदाहरण। –

+1

उदाहरण में दी गई श्रेणियां निरंतर नहीं हैं। यदि कोई 4, या 50 की खोज करता है, तो क्या आप 'शून्य' परिणाम, उपरोक्त सीमा, नीचे या निकटतम, या क्या चाहते हैं? – erickson

+4

@mkal: जिस तरह से आप आवश्यकताओं को बदलने के लिए रहते हैं, आप नरक से प्रबंधक हो सकते हैं :-) –

उत्तर

62

मैं अधिक सामान्य समस्या के लिए कई संभावित समाधानों के बारे में सोच सकता हूं जहां श्रेणियां समान नहीं हैं और 'छेद' हैं। सबसे सरल हैं:

  1. सभी वैध कुंजी मानों के लिए बस एक मानचित्र को पॉप्युलेट करें, एकाधिक कुंजी मैपिंग उसी मान पर मैपिंग के साथ। यह मानते हुए कि आप हैशमैप्स का उपयोग करते हैं, यह सबसे अधिक समय कुशल (ओ (1) लुकअप होना चाहिए), हालांकि आपके पास सेटअप समय पर अधिक काम है और आप अधिक जगह का उपयोग करते हैं।
  2. एक NavigableMap का उपयोग करें और लुकअप करने के लिए floorEntry(key) का उपयोग करें। यह कम समय कुशल (ओ (लॉग (एन) लुकअप), लेकिन और अधिक स्थान की कुशल होना चाहिए।

यहाँ एक समाधान NavigableMaps का उपयोग कर कि मानचित्रण में 'छेद' के लिए अनुमति देता है।

private static class Range { 
    public int upper, value; 
    ... 
} 

NavigableMap<Integer, Range> map = new TreeMap<Integer, Range>(); 
map.put(0, new Range(3, 0));  // 0..3  => 0 
map.put(5, new Range(10, 1));  // 5..10 => 1 
map.put(100, new Range(200, 2)); // 100..200 => 2 

// To do a lookup for some value in 'key' 
Map.Entry<Integer,Range> entry = map.floorEntry(key); 
if (entry == null) { 
    // too small 
} else if (key <= entry.getValue().upper) { 
    return entry.getValue().value; 
} else { 
    // too large or in a hole 
} 

पर दूसरी ओर, अगर वहाँ कोई 'छेद' कर रहे हैं समाधान सरल है:

NavigableMap<Integer, Integer> map = new TreeMap<Integer, Integer>(); 
map.put(0, 0); // 0..4  => 0 
map.put(5, 1); // 5..10 => 1 
map.put(11, 2); // 11..200 => 2 

// To do a lookup for some value in 'key' 
if (key < 0 || key > 200) { 
    // out of range 
} else { 
    return map.floorEntry(key).getValue(); 
} 
+1

यह मौजूदा TreeMap का बहुत अच्छा उपयोग है एक साधारण रेंज खोज करें। ध्यान दें कि यदि ओवरलैपिंग अंतराल हैं, तो दृष्टिकोण उस अंतराल को लुकअप कुंजी के निकटतम निचले कुंजी के साथ वापस कर देगा। इसी तरह, यह दृष्टिकोण किसी दिए गए खोज कुंजी वाले सभी ओवरलैपिंग अंतराल की खोज का समर्थन नहीं करता है, जैसा कि http://stackoverflow.com/questions/1580185/data-structure-for-quick-time-interval-look-up – stackoverflowuser2010

+0

में चर्चा की गई है यदि ओवरलैपिंग श्रेणियां हैं, तो श्रेणियां (सबसे अधिक संभावना) गलत तरीके से निर्दिष्ट हैं। कम से कम, यह मेरा प्रश्न है। –

0

मुझे लगता है कि आप क्या चाहते हैं foo()/10 के साथ कुछ है, लेकिन यह आपको आपके अनुरोध के मुकाबले थोड़ा सा रेंज देगा। यदि आप एक आसान पैटर्न का पालन नहीं करते हैं तो आप हमेशा अपने "मानचित्र" में प्रत्येक आइटम के लिए दो अंतराल के साथ तुलना कर सकते हैं।

3

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

10

छद्म कोड:

  1. रेंज सीमाओं को एक फ्लैट सरणी में स्टोर करें: new int[] {0, 3, 5, 15, 100, 300}
  2. सरणी के माध्यम से बाइनरी खोज जैसे कि सरणी में कोई संख्या डालना। Arrays.binarySearch() देखें।
  3. यदि सम्मिलन बिंदु भी है, तो संख्या किसी भी सीमा में फिट नहीं होती है।
  4. यदि सम्मिलन बिंदु अजीब है, तो यह इसी सीमा में फिट बैठता है। उदाहरण के लिए, उपर्युक्त सरणी में 10 के लिए सम्मिलन बिंदु होगा, इसे 5 और 15 के बीच रखेगा, इसलिए यह दूसरी श्रेणी में है।
+1

नोट: यह केवल तभी काम करता है जब हम पूर्णांक '{0, 1, 2, ...} 'में मैपिंग कर रहे हों। अधिक सामान्य मामलों के लिए, किसी प्रकार का नक्शा इस्तेमाल किया जाना चाहिए। –

0

मुझे लगता है कि सबसे आसान समाधान आपकी श्रेणियों की ऊपरी सीमाओं से मानचित्रों को जोड़ने के लिए मैपिंग जोड़ना होगा, और मैपिंग तक पहुंचने तक केवल अपना नंबर (मानचित्र में कुंजी) बढ़ाएगा (जो कि आपकी संख्या में सीमा के लिए ऊपरी सीमा है)।

एक और तरीका एक श्रेणी में सभी प्रविष्टियों के साथ मानचित्र को पॉप्युलेट करना होगा, और प्रत्येक के लिए मैपिंग जोड़ें।

कौन सा अधिक कुशल है कि क्या यह संभव है पर निर्भर करता है आप सभी नंबरों को बार-बार (उत्तरार्द्ध समाधान का उपयोग) एक श्रेणी में अनुरोध करने के लिए, या बस संख्या में से कुछ कई बार (पहले का उपयोग करें)