【问题标题】:Why is std::set::lower_bound(x) (effectively) defined as the smallest number >= x rather than the largest number <= x?为什么 std::set::lower_bound(x) (有效地)定义为最小数 >= x 而不是最大数 <= x?
【发布时间】:2012-06-29 02:31:11
【问题描述】:

也许我误解了lower bound 的技术定义,但我希望如果我有一个集合a = { 0, 3, 4 } 并计算a.lower_bound(2),结果将是0。 IE。我希望std::set::lower_bound 接近infimum 的数学概念

然而标准库将其定义为不小于(实际上是&gt;=)x 的最大数。

这背后的原因是什么?

【问题讨论】:

  • 考虑迭代器的范围可能更常见,因此当您说“我想要 2 到 5 之间的所有内容”时,迭代器返回是较低的“障碍”。但问题是,为什么你会期望它不是这样? /your/ 背后的原因是什么?
  • 除了出色的答案之外,您还可以通过使用std::prev(iter) if *iter != x 来获得下确界。
  • Corrections — “...标准库将其定义为 最小 不少于...”@KonradRudolph 的建议很好,但首先您还需要检查 set 是否不是空的。对于std::lower_bound免费功能,也可以使用reverse_iterators和std::greater来反转“错误”的方向。
  • 啊,优雅的方法是从s.lower_bound(x) 的结果构造一个std::set::reverse_iterator,然后将其与s.rend() 进行比较。

标签: c++ stl set


【解决方案1】:

[lower|upper]_bound”函数旨在返回集合中的一个位置,您可以在其中插入一个不会违反集合顺序的键。因为 STL 集合的迭代器指向下一个元素之前,所以如果 lower_bound(2) 将迭代器返回到 0,那么插入 2 将违反集合的顺序,现在它将是 {2, 0, 3, 4}。上限用于显示您可以在不违反设置顺序的情况下插入的最后一个位置。

如果您的集合可能有重复的键条目,这是最有用的。考虑{0, 3, 3, 4}lower_bound(3) 会返回一个迭代器到这里:{0, *, 3, 3, 4},而upper_bound(3) 会返回到这里:{0, 3, 3, *, 4}

【讨论】:

    【解决方案2】:

    一起考虑lower_boundupper_bound 的行为可能会有所帮助。

    在 STL 中,范围始终是闭开区间。由两个迭代器firstlast 分隔的范围包括firstlast 之间的所有元素,包括first 和不包括last。使用区间表示法,我们将其表示为 [first, last)

    lower_boundupper_bound 被定义为它们找到比较等于指定值的元素的范围。如果您在lower_bound(x)upper_bound(x) 之间进行迭代,您将遍历所有比较等于x 的元素。如果没有元素等于x,则保证lower_bound(x) == upper_bound(x)

    这个特性对于 std::map 来说不太重要,每个键最多有一个元素,但是对于非唯一关联容器和非成员 std::lower_bound 来说是一个非常有用的特性,它可以与任意序列一起使用已排序的元素。

    [请注意,如果您想要同时获得下限和上限,则应改为调用equal_range,它会同时返回。]

    【讨论】:

    • 也许更重要的是,如果您在lower_bound(n)upper_bound(m) 之间进行迭代,您将访问[n...m) 范围内的所有元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多