在向量中找到最接近的值

时间:2019-01-05 20:54:05

标签: c++ vector iterator lower-bound

我要完成的工作是遍历一个double值的向量,并返回最接近的double的向量位置。我对此有两个问题。

  1. 当尝试使用lower_bound()在向量中找到最接近的双精度值时,如果我输入1,则仅会收到零以外的值。

  2. 我不确定如何使用lower_bound返回矢量位置而不是双精度值。

这是我正在使用尝试的代码的三个主要文件

Convert.cpp

double Convert::convertmVtoK(double value)
{
    double conversion = *std::lower_bound(mV.begin(), mV.end(), value);
    cout<<"This is conversion mV to K"<<" "<< conversion;
}

double Convert::convertKtomV(double value)
{
    double conversion = *std::lower_bound(mV.begin(), mV.end(), value);
    cout<<"This is conversion K to mV"<<" "<< conversion;
}

Conversion.h

class Convert
{
    public:
        Convert();
        virtual ~Convert();
        double convertmVtoK(double mV);
        double convertKtomV(double K);
        void readFile();

    protected:

    private:
        std::ifstream inFile;
        std::vector<double> kelvin,mV,sensitivity;
        double tempKelvin,tempmV,tempSensitivity;
};

#endif // CONVERT_H

Main.cpp

#include "Convert.h"
#include <stdio.h>
#include<fstream>
#include<iostream>


int main()
{
    Convert convert;
    convert.readFile();
   convert.convertmVtoK(2.0);
    convert.convertKtomV(5.000);

    return 0;
}

更新:所以我仍在尝试使用lower_bound()。这是我更新的功能。

double Convert::convertmVtoK(double value)
{
    std::vector<double>::iterator pos;

    pos = std::lower_bound(mV.begin(), mV.end(), value);
    cout<<"This is conversion mV to K"<<" "<< kelvin[(pos-mV.begin())];
}

当前,如果我输入一个浮点值,我仍然无法接收正确的向量值,它将返回0或[0]向量值。

更新2:文本值

1.4 1.644290    -12.5
1.5 1.642990    -13.6
1.6 1.641570    -14.8
1.7 1.640030    -16.0
1.8 1.638370    -17.1
1.9 1.636600    -18.3
2.0 1.634720    -19.3
2.1 1.632740    -20.3

2 个答案:

答案 0 :(得分:1)

您可以将min_element与比较器一起使用,该比较器考虑到value的距离:

// precondition: mV is not empty
double get_closest(double value) const
{
    assert(!mV.empty());
    auto it = std::min_element(mV.begin(), mV.end(), [value] (double a, double b) {
        return std::abs(value - a) < std::abs(value - b);
    });
    assert(it != mV.end());

    return *it;
}

答案 1 :(得分:0)

lower_bound()不会将迭代器返回到最接近的值。它将迭代器返回到您的值之前没有出现的第一个元素,即在这种情况下,第一个element >= 5.000

一种解决此问题的方法,如果您想使用lower_bound()等:

vector<double> v;
double d = 5.0;
auto it = lower_bound(v.begin(), v.end(), d);
if (it == v.begin())
{
    // No elements are smaller than d
    it = v.end();
}
else
{
    --it;
    // it now points to the largest element smaller than d
}

auto jt = upper_bound(v.begin(), v.end(), d);
if (jt == v.end())
{
    // No elements are larger than d
}
else
{
    // jt already points to the smallest element larger than d
}

auto out = it;
if (it == v.end())
{
    out = jt;
}
else if (jt != v.end())
{
    if (d - *it > *jt - d)
    {
        out = jt;
    }
}
// out now points to the value closest to d, or v.end() (if v is empty or only contains d)

上面的代码可以简化为以下等效代码:

vector<double> v;
double d = 5.0;
auto it = lower_bound(v.begin(), v.end(), d);
if (it == v.begin())
{
    it = v.end();
}
else
{
    --it;
}
auto jt = upper_bound(v.begin(), v.end(), d),
     out = it;
if (it == v.end() || jt != v.end() && d - *it > *jt - d)
{
    out = jt;
}

解决此类问题的方法更为紧凑,但这说明了如何通过使用相对简单的概念来解决当前的问题。

lower_bound()upper_bound()的时间复杂度也很好。