【问题标题】:How do map::lower_bound() and map::upper_bound work in C++?map::lower_bound() 和 map::upper_bound 如何在 C++ 中工作?
【发布时间】:2018-09-20 23:57:21
【问题描述】:

我正在尝试让自己熟悉 C++ 中的地图,并且我也在尝试了解一些可以在地图上使用的基本操作。然而,我不明白的仅有两个是lower_bound()upper_bound()。我已经多次查找它们,但不明白它们在做什么。有人可以澄清一下吗?

【问题讨论】:

  • 你有什么不明白的?可能的实施,目的?
  • 他们返回什么以及他们的目的。
  • 类似于std::lower_bound,但适用于std::map。来自算法的文档给出了一些例子。
  • “我已经查了很多次了,但不明白他们在做什么” - 当你“查”的时候,你没有的解释是什么理解?可以提供链接吗?

标签: c++ dictionary std stdmap c++-standard-library


【解决方案1】:

下限和上限可能更容易理解为equal_range

equal_range 返回一对迭代器,当被视为半开区间时,它们的值与您传入的键等效(在< 下)。

一旦你掌握了这一点,lower_bound 返回equal_range 的第一个“开始”迭代器,upper_bound 返回equal_range 的最后一个“结束”迭代器。

直接指定它们会导致您可能会感到困惑的尴尬阅读:“第一个元素不少于”等。除了在狭隘的情况下,没有人会这样想。

【讨论】:

    【解决方案2】:

    要了解lower_bound/upper_bound,您必须记住map 不仅仅是一个将键映射到值的容器,而且与现实世界的词汇表一样,它还强制元素按以下顺序排序键,因此您不仅可以对查找特定项目感兴趣,还可以对快速定位某些实际上可能不存在的键的“周围环境”感兴趣。

    假设您有一个map<string, T>,它将字典中的单词映射到其他东西。如果您想要前缀匹配(例如,所有以“dange”开头的单词),请使用lower_bound,它将返回大于或等于给定值的第一项;所有以该前缀开头的单词,按字典顺序进行比较,都将满足此标准(因此您可能会得到一个指向“危险”的迭代器)。只要前缀匹配(“danger”、“dangerous”、...),您现在就可以向前迭代。

    另一个例子:你有一个从时间戳到事件的映射,你想查看两个时间戳之间发生了什么。您可以使用lower_bound 定位第一个元素>= 而不是初始时间戳,即使这样的时间戳实际上并不对应于任何存储的事件(所以find 不会这样做),然后只要继续前进你在你感兴趣的范围内。

    类似的例子可以用upper_bound 来完成——虽然老实说我认为我很少使用它。

    【讨论】:

    • 这其实是不准确的。与其使用的措辞相比,lower_bound 不会为您提供小于当前键的最大键。这实际上是一个无赖,因为这是一个非常有用的功能。但它没有这样做。
    • @Amir:虽然你说的是真的(你描述的通常是我自己经常实现的有用操作,基于lower_bound),但我重新阅读了我的答案几次,而且我没有看到我在哪里说过lower_bound 返回的最大密钥小于请求的密钥,我想我总是说它返回第一个密钥>=...你能准确指出我写错的地方吗措辞?顺便说一句,对于上限/下限术语,它实际上与 C++ 中[, ) 间隔的一般用法一致。
    • 你是对的。我想我在快速阅读时可能误解了您提到的一些观点。您正确地提到了 lower_bound 将给出等于或大于我们正在搜索的键的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多