如何正确调用std::lower_bound()?

how to correctly call std::lower_bound()?

提问人:CosmeticMichu 提问时间:11/15/2022 最后编辑:CosmeticMichu 更新时间:11/15/2022 访问量:69

问:

我正在绘制一个包含两列(频率和电压)的数据文件,我需要寻找最接近给定值的值。问题是我的数据表现得像高斯,所以有两个值满足这个要求,高于和低于最大值。首先,我将数据文件中的每一列放入一个数组中,并定义了这个函数来查找这些值valvector

#include<iostream>
#include<vector>
#include<cmath>

typedef std::vector <double> vector;

vector posi(vector vec, int ref, double val);

int main(void){

  //define a custom volt vector here e.g vector volt{...};
  auto auxvmax = std::max_element(volt.begin(), volt.end());
  int posvmax = auxvmax - volt.begin();//this is what I take as ref value
  
  double val = 0.7;
  vector fpos(2, 0.0);
  fpos = posi(volt, posvmax, val);
  double auxf_1 = fpos[0];
  double auxf_2 = fpos[1];
  std::cout << "closest value to " << val << " are " << volt[auxf_1] << " below and " << volt[auxf_2] << " above\n";
return 0;
}

vector posi(vector vec, int ref, double val){

  vector posvec(2, 0.0);
  auto pos1 = std::lower_bound(vec.begin(), vec.begin() + ref, val);
  auto pos2 = std::lower_bound(vec.begin() + ref, vec.end(), val);

  double val1a = *(pos1 - 1.0);
  double val1b = *pos1;
  double val2a = *(pos2 - 1.0);
  double val2b = *pos2;

  if(fabs(val - val1a) < fabs(val - val1b)){
    posvec[0] = pos1 - vec.begin() - 1;
  }
  if(fabs(val - val1a) > fabs(val1b)){
    posvec[0] = pos1 - vec.begin();
  }
  if(fabs(val - val2a) < fabs(val - val2b)){
    posvec[1] = pos2 - vec.begin() - 1;
  }
  if(fabs(val - val2a) > fabs(val - val2b)){
    posvec[1] = pos2 - vec.begin();
  }

  return posvec;
}

让我解释一下我是如何以及为什么这样构造函数的,这样你就可以告诉我我哪里错了。

基本上,我尝试在值所在的向量的两个“区域”中使用,这是为了让程序在每个区域中只寻找一个最接近的值,我知道最大值在哪里(在函数中,通过),所以我可以很容易地进行拆分。 是在向量中分配最大值的位置(迭代器),因此它应该获得最接近该位置上方和下方的值。std::lower_bound()mainstd::max_element()refvecvalref

接下来,它只确保该值是最接近的,考虑最小的下一个值(默认值由 和前一个值给出,在每种情况下(区域)中最接近。最后,每个值在向量中的位置存储到向量中(因为我必须得到电压最接近的频率,所以我不需要电压值,而是他的位置,因为 freq 和 volt 成对)。valstd::lower_bound())posvecval

当我编译它时,它没有给出错误,没有警告,但最接近的值不是最接近的。我发现 (cppreference) 得到的数组必须从低到最大排序,并且我的数据从最大值以下的最低到最大,以及最大值到最大值以上的最低排序,所以上面的数据应该有问题,但是 - 这是我的问题 - 为什么即使使用下面的数据,我也没有得到最接近的值?我是不是没有得到行为的东西?,当我使用 if 语句时,它可能是什么?输出,打印示例电压矢量如下std::lower_bound()std::lower_bound()

here

在这里,您可以看到“最接近”的值确实是最远的。

提前感谢您的帮助。

编辑:在评论中询问,输出是

closest values to 0.7 are 0.485437 below, and 0.320388 above
0.485437
0.500971
0.524272
0.543689
0.563107
0.594175
0.617476
0.648544
0.679612
0.71068
0.741748
0.786408
0.825243
0.864078
0.893204
0.932039
0.961165
0.980583
0.990291
1
0.990291
0.961165
0.941748
0.893204
0.854369
0.805825
0.757282
0.708738
0.669903
0.621359
0.582524
0.547573
0.512621
0.481553
0.454369
0.427184
0.403883
0.384466
0.361165
0.341748
0.320388
C++ 数组 C++-标准库

评论

0赞 Alan Birtles 11/15/2022
请展示一个最小的可重复示例
6赞 Mark Ransom 11/15/2022
lower_bound仅在排序序列上正常工作。听起来不像是描述您的数据。
1赞 HolyBlackCat 11/15/2022
它本身不必排序,只需根据您要查找的元素进行分区(即所有小于它的元素必须先于不小于它的所有元素)。
1赞 HolyBlackCat 11/15/2022
@MarkRansom 它不会注意到它们乱序,因为它只会将它们与目标值进行比较。请参阅有关范围要求的 cpreference
2赞 HolyBlackCat 11/15/2022
@CosmeticMichu我认为你的范围很好,你只需要作为第二个的比较器。std::greater<>{}lower_bound

答: 暂无答案