代码之家  ›  专栏  ›  技术社区  ›  Bill the Lizard

在C++中双倍数组中搜索最近值?

  •  7
  • Bill the Lizard  · 技术社区  · 16 年前

    指数 最近的 数组中的值是否为给定的双精度值?

    例如,给定以下数组

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

    函数调用

    search(myarray, 1.6);
    

    应该回来 3 ,最接近1.6的元素的索引,而不是 -1 (或某些其他标志值)指示未找到值1.6。

    5 回复  |  直到 16 年前
        1
  •  12
  •   bayda    16 年前

    大概 std::lower_bound std::upper_bound

        2
  •  6
  •   Luc Touraille    16 年前

    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
    
        3
  •  3
  •   eduffy    16 年前

    数组是否保证按升序排列?如果是,请说明 std::lower_bound 一看。

        4
  •  3
  •   Rexxar    16 年前

    我想我的例子正是你想要的:

    (我使用std::min_元素和函子)

    #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
    }
    
        5
  •  0
  •   Indy9000    16 年前
    #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;
     }
    
    推荐文章