我要完成的工作是遍历一个double值的向量,并返回最接近的double的向量位置。我对此有两个问题。
当尝试使用lower_bound()
在向量中找到最接近的双精度值时,如果我输入1,则仅会收到零以外的值。
我不确定如何使用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
答案 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()
的时间复杂度也很好。