簡體   English   中英

使用std :: equal_range搜索某些范圍內的向量

[英]using std::equal_range to search the vector within some ranges

我有一個std :: vector,元素為pair,需要在某些范圍內找到第一個組件的所有元素,例如,找到所有元素,使得abs(第一個組件的值 - 引用)<0.01,我得到了來自其他帖子的代碼

bool comp(pair<double, double> v1, pair<double, double> v2)
{
  return (abs(v1.first-v2.first)<0.001);
}

vector< pair<double, double> data;
for (int i=0; i<10; i++)
{
  double a, b; 
  // a & b are initialized randomly (the code was not shown here)
  data.push_back(make_pair(a, b));
}

// we sort the vector here based on the pair.first (code not shown)

// compval is used as reference value, i.e. we are going to find all elements with     abs(pair.first-ref.first)<0.01
pair<double, double> ref
ref.first = 0.5;
ref.second = 0.5;

std::pair< vector< pair<double, double>::iterator, vector< pair<double, double>::iterator> const range = std::equal_range(data.begin(), data.end(), ref, comp);

但是如果查看結果范圍給出的所有元素,您將看到數據的所有元素而不是滿足abs(pair.first-ref.first)<0.01的元素將被返回。 這是我在代碼中遺漏的東西嗎? 謝謝。

equal_range需要排序范圍。

比較函數隱含的順序與您對范圍進行排序的順序不匹配 - 因此對equal_range的調用具有未定義的行為。

例如 - 假設您的列表包含{{.5, 0}, {.6, 0}} (這些已排序),然后您應用std::bind(comp({.5,.5},_1))每個元素。

comp({.5,.5},{.5,0})將返回true。

comp({.5,.5},{.6,0})將返回false。

您的排序順序是:“。 .5小於.6 ”,但同時您的comp函數說“ .6小於.5 ”(因為有一個值小於.5但不是小於.6 )。 這是矛盾的,是你問題的原因。

要實際找到std::bind(comp({.5,.5}, _1))返回true的所有元素,可以使用std::copy_if(data.begin(), data.end(), some_output_iterator, std::bind(comp(ref, std::placeholders::_1))) (盡管有多種不同的方法可以做到這一點,具體取決於你的確切需求)。

我認為你應該在函數comp()使用fabs而不是abs

您的比較函數不滿足嚴格弱排序的要求,即對於兩個元素a和b,如果comp(a, b) == truecomp(b, a)應該為false

你可能想要更像這樣的東西:

struct Comp {
  double target;
  bool operator()(const pair<double, double>& lhs,
                  const pair<double, double>& rhs) const {
    return abs(lhs.first - target) < abs(rhs.first - target);
  }
};

vector< pair<double, double> > data;
data.push_back(make_pair(0.1, 1.0));
data.push_back(make_pair(0.15, 1.2));
data.push_back(make_pair(0.189, 2.1));
data.push_back(make_pair(0.19, -2.1));
data.push_back(make_pair(0.192, 3.1));
data.push_back(make_pair(0.2, 0.1));
data.push_back(make_pair(0.205, 0.1));
data.push_back(make_pair(0.205, 0.0));
data.push_back(make_pair(0.206, 12.1));
data.push_back(make_pair(0.21, -12.9));
data.push_back(make_pair(0.3, 3.4));
data.push_back(make_pair(0.5, 7.5));
// We *must* sort the vector using the same comparison function that we're
// about to use to get the lower and upper bounds
Comp comp;
comp.target = 0.2;
sort(data.begin(), data.end(), comp);

// Get the lower bound
pair<double, double> low(make_pair(comp.target, 0.0));
vector< pair<double, double> >::iterator lower =
    lower_bound(data.begin(), data.end(), low, comp);

// Get the upper bound
pair<double, double> up(make_pair(comp.target + 0.01, 0.0));
// N.B. use "lower_bound" here to get upper bound of target + 0.01 exclusive.
//      If we want to include target + 0.01, use "upper_bound"
vector< pair<double, double> >::iterator upper =
    lower_bound(data.begin(), data.end(), up, comp);

for_each(lower, upper, [](const pair<double, double> &data_point) {
  cout << data_point.first << "\t" << data_point.second << "\n";
});


哪個輸出:

0.2     0.1
0.205   0.1
0.205   0
0.206   12.1
0.192   3.1
0.21    -12.9

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM