说我有以下代码
#include <iostream>
#include <set>
int main ()
{
std::set<int> myset;
int inf, sup;
inf = 25; sup = 60;
for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
return 0;
}
我试图弄清楚标准库是否提供了任何方法或方法组合,这些方法允许我获得两个迭代器it_l, it_u
,以便覆盖范围[inf,sup]。我试过使用lower_bound,upper_bound,但我误解了它们是如何工作的。这个想法是避免写循环(因为我知道我可以为这个任务编写自己的函数,但也许有一些我不知道的替代方法。)
更新:预期输出的一些示例(在我的示例中)
inf =25; sup = 60
我希望{30,40,50,60}
如果改为
inf=30; sup = 60
我希望{30,40,50,60}
如果
inf=25; sup = 65
我希望{30,40,50,60}
显然存在误解,或者也许是我,我没有正确表达我想做的事情。
当我说inf和sup时,请将它们视为实际间隔的极值。一旦你做了这样的假设,我想要检索的是区间[inf,sup]和由set对象指定的离散集之间的交集。我刚刚说的和我的例子之间是否存在一些矛盾?
允许A={10 20 30 40 50 60 70 80 90}
,B1=[25,60]
,B2=[30,60]
和B3=[25,65]
对于每个i=1,2,3
A
和Bi
之间的交集给出了我在示例中所说的内容。
答案 0 :(得分:4)
这对我来说很好用:
#include <iostream>
#include <set>
template <typename T>
std::pair<typename std::set<T>::const_iterator, typename std::set<T>::const_iterator>
infsup(const std::set<T>& set, const T& inf, const T& sup)
{
return std::make_pair(set.lower_bound(inf), set.upper_bound(sup));
}
int main ()
{
std::set<int> myset;
int inf, sup;
for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
for (auto its = infsup(myset, 30, 60); its.first != its.second; ++its.first)
{
std::cout << " " << *its.first; // 30 40 50 60
}
std::cout << std::endl;
for (auto its = infsup(myset, 25, 65); its.first != its.second; ++its.first)
{
std::cout << " " << *its.first; // 30 40 50 60
}
std::cout << std::endl;
return 0;
}
对inf
使用lower_bound
意味着启动迭代器将指向第一个不小于inf
的元素,因此满足条件想要达到范围的低端。
对sup
使用upper_bound
意味着结束迭代器将指向_第一个大于sup
_的元素。请注意,在C ++中,结束迭代器始终将指向范围的末尾,因此将包含sup
。
编辑以反映评论中的讨论(感谢@Useless指出):请注意,这适用于空结果范围,例如。
inf
和sup
都小于集合inf=25, sup=29
)但是如果你选择inf > sup
以便返回的迭代器引用不同的元素,那么its.first > its.second
会导致for
循环(就像我上面写的那样)失败。因此,您需要确保inf <= sup
(就像您可能正在编写的任何其他for
循环一样)。
答案 1 :(得分:1)
看起来你只想要这个:
auto it_l = myset.lower_bound(inf);
auto it_u = myset.lower_bound(sup + 1);
通过这种方式,您将获得半开的时间间隔[it_l, it_u)
,使其中的所有元素i
都来自myset
并且是inf <= i <= sup
(即恰恰是您想)。半开放迭代器间隔是整个标准库的工作区域,所以你应该没问题。
答案 2 :(得分:0)
C ++适用于半开范围。也就是说,[inf, sup)
,永远不会[inf, sup]
。标准库很好地支持半开放式习语:只需使用std::set::lower_bound
和std::set::upper_bound
。 (不是std::upper bound
等)。封闭范围不是,如果你坚持使用它,你就是你自己。我建议采用标准方式并在任何地方切换到半开放范围。
答案 3 :(得分:0)
不清楚为什么你说上限和下限不能做你想做的事。
lower_bound将返回指向您要查找的第一个元素的迭代器(第一个元素不小于参数)
upper_bound为你提供了大于参数的第一个元素(在你的例子中为70),但是stl迭代器是如何工作的,结束点是一个超出最后一个元素。
如果您真的需要副本,可以使用这两个迭代器制作元素的副本 - 但您也可以使用它们来访问原始集合的元素 - 并且该范围将包括60而不是70示例