Find Closest Value in Vector

时光怂恿深爱的人放手 提交于 2020-01-24 13:03:09

问题


What I am trying to accomplish is iterating through a vector of double values and returning the vector position of the closest possible double. I am having two issues with this.

  1. When attempting to find the closest double value in the vector using lower_bound(), i only receive a value other than zero if I enter 1.

  2. I am not sure how to use lower_bound to return a vector position instead of a double value.

Here is my three main files I am using with attempted code

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;
}

Update: So I am still attempting to use lower_bound(). Here is my updated function.

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())];
}

Currently the if I input a float value I am still not able to recieve the correct vector value, it either returns 0 or the [0] vector value.

Update 2: text values

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

回答1:


You can use min_element with a comparator that takes the distance to value into account:

// 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;
}



回答2:


lower_bound() does not return an iterator to the closest value. It returns an iterator to the first element which does not go before your value, i.e. in this case the first element >= 5.000

One way to solve this, if you want to use lower_bound() etc :

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)

The above code can be reduced to this equivalent code:

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;
}

There are more compact ways to go about this sort of problem, but this illustrates how to solve the problem at hand by using relatively simple concepts.

The time complexity of lower_bound() and upper_bound() is quite good, too.



来源:https://stackoverflow.com/questions/54056171/find-closest-value-in-vector

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!