如何在std::set中获得给定下界和上界的映射中的值范围?
How Can I get a range of values in a map for given lower bound and upper bound in an std::set?
假设我有以下代码
#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
I expect {30,40,50,60}
inf=25; sup = 65
I expect {30,40,50,60}
显然有误解,或者可能是我没有正确表达我想要做的。
当我说inf和sup时,请将它们表示为实区间的极值。一旦你做了这样的假设,我想要检索的是区间[inf,sup]和由集合对象指定的离散集合之间的交集。我刚才说的和我举的例子有矛盾吗?
让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
之间的交集正好给出了我在我的例子中所说的。
这对我来说很好:
#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
意味着end迭代器将指向_第一个大于sup
_的元素。请注意,在c++中,end迭代器总是指向刚好超出范围的end,因此将包含sup
。
编辑以反映评论中的讨论(感谢@Useless指出这一点):注意,这对空结果范围有效,例如
- 当
inf
和sup
都小于集合 中最小的元素时 - 当两者都大于最大元素
- 当[inf, sup]中没有元素时(在您的示例中为
inf=25, sup=29
)
但是,如果您选择inf > sup
,以便返回的迭代器指向不同的元素,则选择its.first > its.second
,这将使for
循环(如上所述)失败。因此,确保inf <= sup
(就像您可能编写的任何其他for
循环一样)由您决定。
看来你只是想要这个:
auto it_l = myset.lower_bound(inf);
auto it_u = myset.lower_bound(sup + 1);
这样,您将获得半开间隔[it_l, it_u)
,这样其中的所有元素i
都来自myset
并且是inf <= i <= sup
(即正是您想要的)。半开迭代器间隔是整个标准库都使用的,所以你应该没问题。
我不知道为什么你说的上限和下限不能做你想做的。
lower_bound将返回一个迭代器,该迭代器指向您要查找的第一个元素(不小于参数的第一个元素)
upper_bound给你第一个大于参数的元素(在你的例子中是70),但这就是STL迭代器的工作方式,end指向one- beyonthe -last-element。
这两个迭代器可以用来复制元素,如果你真的想要一个副本——但你也可以用它们来访问原始集合的元素——在你的例子中,这个范围包括60,而不是70。
c++使用半开范围。也就是[inf, sup)
,而不是[inf, sup]
。标准库很好地支持半开放范围的习惯用法:只需使用std::set::lower_bound
和std::set::upper_bound
。(不是std::upper bound
等)。如果你坚持要用,那就只能靠你自己了。我建议采用标准方法,并在所有地方切换到半开放范围。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何在C++中访问有序映射中的键的范围/间隔?
- 迭代嵌套映射与范围为循环:没有名为"first"的成员
- 将整数范围映射到另一个范围
- 在C++或Python中,将浮点值映射到指定范围内的新值
- 将矢量映射到特定范围
- 定义基于模板的映射指针,以便在验证范围时将 int 解析为枚举
- c++将大型数字字符串映射到数字字符串范围
- C++ 映射擦除范围
- 整数宇宙映射数组到固定范围的应用与实现
- 将值映射到某个范围
- 在映射中存储一定范围内的值
- 如何在std::set中获得给定下界和上界的映射中的值范围?
- 如何使用基于范围的for循环修改映射中的值
- 在从一个范围映射到另一个范围时避免重复值
- 将有符号整数范围映射为无符号
- 以将阵列中的数字范围映射为均匀随机1到100