2009-03-30 11 views
6

मेरे पास C++ में डबल मानों की एक क्रमबद्ध सरणी है। क्या कोई एसटीएल फ़ंक्शन है जो इंडेक्सके निकट किसी दिए गए डबल मान के लिए सरणी में मूल्य लौटाएगा?सी ++ में युगल की सरणी में निकटतम मूल्य के लिए खोजें?

उदाहरण के लिए

, निम्नलिखित सरणी दिया

double myarray[5] = { 1.0, 1.2, 1.4. 1.5, 1.9 }; 

समारोह कॉल

search(myarray, 1.6); 

3, 1.6 के सबसे नजदीक तत्व के सूचकांक के बजाय -1 (या कुछ अन्य ध्वज मान चाहिए) यह दर्शाता है कि मान 1.6 नहीं मिला था।

+0

हम उपयोग कर सकते हैं एक functor के साथ "std :: min_element", मेरा उदाहरण देखें। – Rexxar

+0

बहुत अधिक [इस पोस्ट] का एक डुप्लिकेट (http://stackoverflow.com/questions/469477/find-nearest-points-in-a-vector)। – mwigdahl

उत्तर

13

शायद std::lower_boundstd::upper_bound आपकी मदद करेगा।

3

क्या सरणी आरोही क्रम में होने की गारंटी है? यदि ऐसा है, तो std::lower_bound एक नज़र दें।

+0

हां, यह आरोही क्रम में होने की गारंटी है। std :: lower_bound काम किया, धन्यवाद। –

2

मुझे लगता है कि मेरी उदाहरण वास्तव में आप क्या चाहते हैं:

(मैं std :: min_element और एक functor का उपयोग)

#include <algorithm> 
#include <cmath> 

const int ARRAY_LENGTH = 5; 
double myarray[ARRAY_LENGTH] = { 1.0, 1.2, 1.4, 1.5, 1.9 }; 

struct CompareDistanceFromLevel 
{ 
    CompareDistanceFromLevel(double cLevel) : level(cLevel) {} 

    bool operator()(double lhs, double rhs) 
    { 
     return std::abs(level - lhs) < std::abs(level - rhs); 
    } 

private: 
    double level; 
}; 

size_t getPositionOfLevel(double level) 
{ 
    double *result; 
    result = std::min_element(myarray, myarray+ARRAY_LENGTH, CompareDistanceFromLevel(level)); 
    return (result-myarray); // returns the index 
} 
4

यहाँ std::lower_bound का उपयोग कर एक सामान्य समाधान है:

template <typename BidirectionalIterator, typename T> 
BidirectionalIterator getClosest(BidirectionalIterator first, 
           BidirectionalIterator last, 
           const T & value) 
{ 
    BidirectionalIterator before = std::lower_bound(first, last, value); 

    if (before == first) return first; 
    if (before == last) return --last; // iterator must be bidirectional 

    BidirectionalIterator after = before; 
    --before; 

    return (*after - value) < (value - *before) ? after : before; 
} 

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

जब से तुम सूचकांक और नहीं पुनरावर्तक चाहते हैं, आप एक छोटे से सहायक समारोह लिख सकते हैं:

template <typename BidirectionalIterator, typename T> 
std::size_t getClosestIndex(BidirectionalIterator first, 
          BidirectionalIterator last, 
          const T & value) 
{ 
    return std::distance(first, getClosest(first, last, value)); 
} 

और अब आप इस तरह एक कोड के साथ अंत:

const int ARRAY_LENGTH = 5; 
double myarray[ARRAY_LENGTH] = { 1.0, 1.2, 1.4. 1.5, 1.9 }; 

int getPositionOfLevel(double level) 
{ 
    return getClosestIndex(myarray, myarray + ARRAY_LENGTH, level); 
} 

जो देता है निम्न परिणाम:

level | index 
0.1 | 0 
1.4 | 2 
1.6 | 3 
1.8 | 4 
2.0 | 4 
+1

+1 - मैंने आपके कोड का उपयोग नहीं किया, लेकिन इससे मुझे अपने आप में एक बग खोजने में मदद मिली। –

0
#include "stdafx.h" 
#include <limits> 

using namespace std; 

static const int array_len = 5; 
double myarray[array_len] = { 1.0, 1.2, 1.4, 1.5, 1.9 }; 

int approx_search(const double val) 
{ 
    double min_val = numeric_limits<double>::max(); 
    int index = 0; 

    for(int i=0;i<array_len;++i) 
    { 
     double diff = abs(myarray[i] - val); 
     if(diff<min_val) 
     { 
      min_val = diff; 
      index = i; 
     } 
    } 
    return index; 
} 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    printf("approximate %d\n",approx_search(1.6)); 
    printf("approximate %d\n",approx_search(1.7996)); 
    printf("approximate %d\n",approx_search(1.4996)); 
    printf("approximate %d\n",approx_search(0.0002)); 

    return 0; 
} 
संबंधित मुद्दे