2010-11-16 8 views
5

समान प्रश्न: "Finding closest number in an array" (जावा में) और "find nearest match to array of doubles" (वास्तव में भूगोल समस्या)।मुझे मनमानी (गैर-सदस्य) संख्या में सबसे नज़दीकी सरणी तत्व कैसे मिल सकता है?

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

उदाहरण के लिए

, निम्नलिखित पंक्ति का उपयोग करते:

  • 1,8
  • 2,4
  • 2,7
  • 3,1
  • 4,5

2,5 का पता कर रहा 1 के एक सूचकांक के साथ वापसी होगी , 2.4 के मूल्य के अनुरूप।

बोनस मानों को पहचानने के लिए बिंदु जो सरणी तत्वों की सीमा के बाहर पूरी तरह से झूठ बोलते हैं। उदाहरण के लिए, ऊपर सूचीबद्ध सरणी का उपयोग करके, आपका कोड यह तय कर सकता है कि 4.6 है, लेकिन 5.9 बाहर है। यदि आप इस सवाल के इस भाग को आजमा देना चाहते हैं, तो विनिर्देश आपके हाथों में हैं।

+0

[संख्या के संग्रह में सबसे निकटतम मिलान ढूँढना] के संभावित डुप्लिकेट (http: // stackoverflow।कॉम/प्रश्न/445782/खोज-निकटतम-मिलान-इन-कलेक्शन-ऑफ-नंबर) – bzlm

उत्तर

10

Array.BinarySearch है, जो देता है:

निर्दिष्ट सरणी में निर्धारित मूल्य के सूचकांक, यदि मान पाया जाता है। यदि मान नहीं मिला है और मान सरणी में एक या एक से अधिक तत्वों से कम है, तो ऋणात्मक संख्या जो कि पहले तत्व की अनुक्रमणिका का बिटवाई पूरक है जो मान से बड़ा है। यदि मान नहीं मिला है और मान सरणी में किसी भी तत्व से अधिक है, तो ऋणात्मक संख्या जो बिटवाईयर पूरक है (अंतिम तत्व प्लस 1 की अनुक्रमणिका)।

अब जब कि तुम, वहाँ जिस तरह की 100% मिलेगा नहीं के बाद से आपको पता चल जाएगा संख्या या तो कम से कम या मैच से अधिक है, लेकिन यह वास्तव में केवल जांच करने के लिए दो सूचकांक के साथ छोड़ देता है।

0

कुछ इस तरह: इस LINQ का उपयोग कर ऐसा करने के लिए

double[] values = new double[] 
{ 
    1.8, 
    2.4, 
    2.7, 
    3.1, 
    4.5 
}; 

double difference = double.PositiveInfinity; 
int index = -1; 

double input = 2.5; 

for (int i = 0; i < values.Length; i++) 
{ 
    double currentDifference = Math.Abs(values[i] - input); 

    if (currentDifference < difference) 
    { 
     difference = currentDifference; 
     index = i; 
    } 

    // Stop searching when we've encountered a value larger 
    // than the inpt because the values array is sorted. 
    if (values[i] > input) 
     break; 
} 

Console.WriteLine("Found index: {0} value {1}", index, values[index]); 
6

एक तरह से इस तरह है:

public int GetClosestIndex(List<double> doublelist, double targetvalue) 
{ 
    return doublelist.IndexOf(doublelist.OrderBy(d => Math.Abs(d - targetvalue)).ElementAt(0)); 
} 

यह कुछ प्रदर्शन के मुद्दों हो सकता है, लेकिन सूची है कि लंबे समय तक नहीं है, तो यह एक समस्या पैदा नहीं करना चाहिए। साथ ही, यदि दो तत्व लक्षित मूल्य से समान रूप से दूर हैं, तो यह उन लोगों की पहली अनुक्रमणिका लौटाएगा।

+0

+1 अच्छा जवाब ;-) – Steven

+0

@ स्टेवन - धन्यवाद। अपने आप के दृष्टिकोण में काफी समान;) –

+0

@ ओविंद: और आप हमारे से 22 सेकंड तेज हैं: '( – Steven

3
शायद

नहीं सबसे तेजी से समाधान है, लेकिन निश्चित रूप से सुखद आंख कैंडी:

double search; 
double[] array; 

var nearest = (
    from value in array 
    orderby Math.Abs(value - search) 
    select value).First(); 

var index = array.IndexOf(nearest); 

ध्यान दें कि यह पूरी तरह से एक द्विआधारी खोज एल्गोरिथ्म की तुलना में धीमी हो जाएगा, यह सरणी में प्रत्येक तत्व और छँटाई साधन संसाधित करने की जरूरत है क्योंकि उन वस्तुओं की एक हैश तालिका का निर्माण।

+0

ध्यान दें कि वह निकटतम मूल्य की अनुक्रमणिका मांग रहा है, न कि निकटतम मूल्य। –

+0

यह एक अच्छा दृष्टिकोण है हालांकि :) –

+1

@ ओविंद: आप सही हैं। ठीक कर दिया। – Steven

0
List<int> results; 
int target = 0; 
int nearestValue = 0; 
if (results.Any(ab => ab == target)) { 
    nearestValue= results.FirstOrDefault<int>(i => i == target); 
} else { 
    int greaterThanTarget = 0; 
    int lessThanTarget = 0; 
    if (results.Any(ab => ab > target) { 
     greaterThanTarget = results.Where<int>(i => i > target).Min(); 
    } 

    if (results.Any(ab => ab < target)) { 
     lessThanTarget = results.Where<int>(i => i < target).Max(); 
    } 

    if (lessThanTarget == 0) { 
     nearestValue= greaterThanTarget; 
    } else if (greaterThanTarget == 0) { 
     nearestValue = lessThanTarget; 
    } else { 
     if (target - lessThanTarget < greaterThanTarget - target) { 
      nearestValue = lessThanTarget; 
     } else { 
      nearestValue = greaterThanTarget; 
     } 
    } 
} 
+2

कृपया, कुछ योगदान दें, आपके योगदान का कुछ विवरण –

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