我试图找到包含int值i的所有范围[a,b],其中a&lt; = i&lt; = b。我正在使用set<std:pair<int,int>>
作为范围集。
在下文中,在vector<int>
上使用相等范围会产生开始,并且在范围结束时产生一个范围。
当我为set<pair<int,int>>
执行相同操作时,结果将在范围结束时开始和结束,因此不包括包含该值的范围。
#include <set>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int ia[] = {1,2,3,4,5,6,7,8,9,10};
set<int> s1(begin(ia),end(ia));
auto range1 = s1.equal_range(5);
cout << *range1.first << " " << *range1.second << endl; //prints 5 6
pair<int,int> p[] = {make_pair(1,10),
make_pair(11,20),
make_pair(21,30),
make_pair(31,40)};
set<pair<int,int>> s(begin(p), end(p));
auto range = s.equal_range(make_pair(12,12));
cout << range.first->first << " " << range.first->second << endl; //prints 21 30, why?
cout << range.second->first << " " << range.second->second << endl; //prints 21 30
}
prints
5 6
21 30
21 30
为什么set<pair<int,int>>
上的equal_range不包括包含值(12)的范围,即[11.20]
答案 0 :(得分:4)
equal_range
表现完全正确:
assert( std::make_pair(11, 20) < std::make_pair(12, 12) );
assert( std::make_pair(12, 12) < std::make_pair(21, 30) );
[11,20]不是一个范围,它是一对。这对[12,12]不在“另一对”之内,甚至没有任何意义。
[12,12]不在“内”[11,20],它比它更大。 std::pair
的小于运算符首先比较第一个元素,并且只有它们相等才会查看第二个元素,因此make_pair(11,x)
小于make_pair(12, y)
任何x
和y
所以equal_range
告诉你[12,20]会在[11,20]之后和[21,30]之前插入,这是正确的。
如果你想将对作为值的范围来处理你需要编写代码来做到这一点,不要假设对的内置比较就是这样做的。你实际上是想在一系列int中找到一个int 12,但是已经编写了代码来找到一对int的一对[12,12]。那不是一回事。
答案 1 :(得分:3)
该范围内不包含[11, 20]
,因为该范围内不包含任何。 [12, 12]
没有相同的元素,因此它返回一个空范围(由半开区间[x, x)
表示)。
BTW取消引用范围的上限可能会调用未定义的行为,因为它可能等于s.end()
。
答案 2 :(得分:1)
对[12, 12]
在[11, 20]
之后和[21, 30]
之前排序。
std::set::equal_range()包含一系列相等的元素。您的集合中没有相同的元素(尤其不是[11, 20]
),因此equal_range()
会返回[21, 30], [21, 30]
。
答案 3 :(得分:1)
equal_range
以先调用lower_bound,然后调用upper_bound来搜索其余数据集。
template <class ForwardIterator, class T>
pair<ForwardIterator,ForwardIterator>
equal_range ( ForwardIterator first, ForwardIterator last, const T& value )
{
ForwardIterator it = lower_bound (first,last,value);
return make_pair ( it, upper_bound(it,last,value) );
}
看看你的样本:
它调用lower_bound
来定位值的下限(对(12,12),到达
pair<int,int> p[] = {make_pair(1,10),
make_pair(11,20),
make_pair(21,30), // <--- lower_bound() points to here
make_pair(31,40)};
然后它调用upper_bound()来搜索(21,30),(31,40)并且它找不到它,它返回(21,30)
答案 4 :(得分:1)
我不认为你的std::set<std::pair<int, int> >
在与整数相交时不会对你有多大帮助:你可以找到s.lower_bound(std::make_pair(i + 1, i + 1)
来切断搜索,但所有范围从索引开始都低于如果第二个边界足够大,i + 1
可能包含值i
。可能有帮助的是,如果您知道范围的最大大小,在这种情况下,您可以通过s.lower_bound(std::make_pair(i - max_range_size, i - max_range_size))
将搜索范围限制在前面。您需要依次检查每个范围,以确定您的i
是否属于它们:
auto it = s.lower_bound(std::make_pair(i - max_range_size, i - max_range_size));
auto upper = s.lower_bound(std::make_pair(i + 1, i + 1));
for (; it != upper; ++it) {
if (i < it->second) {
std::cout << "range includes " << i << ": "
<< [" << it.first << ", " << it->second << "]\n";
}
(或类似的东西......)