我有一个std :: vector,元素作为对,需要在某些范围内找到第一个组件的所有元素,例如,找到所有元素,使得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)&lt; 0.01的元素将被返回。这是我在代码中遗漏的东西吗?感谢。
答案 0 :(得分:2)
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
小于{{{ 1}}“(因为有一个小于.5
但不小于.5
的值。这是矛盾的,也是你问题的原因。
要实际找到.6
返回true的所有元素,您可以使用std::bind(comp({.5,.5}, _1))
(尽管有多种不同的方法可以执行此操作,具体取决于您的具体需求)。
答案 1 :(得分:0)
我认为您应该在函数fabs
中使用abs
而不是comp()
。
答案 2 :(得分:0)
您的比较函数不满足严格弱排序的要求,即对于两个元素,例如a和b,如果comp(a, b) == true
则comp(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