[英]Using std::equal_range to find the range of prefixes that occur in a vector of strings
[英]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) == 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.