【问题标题】:Test lower_bound's return value against the end iterator针对结束迭代器测试 lower_bound 的返回值
【发布时间】:2012-01-05 10:38:07
【问题描述】:

在 Scott Meyers 的有效 STL 中(第 195 页)有以下行:

“必须测试lower_bound 的结果,看它是否指向您要查找的值。与find 不同,您不能只针对结束迭代器测试lower_bound 的返回值。”

谁能解释为什么你不能这样做?对我来说似乎工作得很好。

【问题讨论】:

  • 这本书当时的上下文是什么?不知道这本书在说什么,令人困惑。是说使用lower_bound 来查看集合中是否包含值吗?

标签: c++ stl map iterator lower-bound


【解决方案1】:

它对你来说很好,因为你的元素存在。

lower_bound 返回第一个元素的迭代器不小于给定值,upper_bound 返回第一个元素的迭代器大于给定值.

给定数组1, 2, 3, 3, 4, 6, 7lower_bound(..., 5) 将返回一个指向 6 的迭代器。

因此,检查值是否存在的两种方法:

  • 使用equal_range 也可以得到upper_bound(分别计算lower_boundupper_bound 可能不是最优的)。如果边界之间的std::distance 大于0,则元素存在。

    1, 2, 3, 3, 4, 6, 7
    std::distance(std::lower_bound(v.begin(),v.end(),5), std::upper_bound(v.begin(),v.end(),5)) == 0 // 6 is absent
    std::distance(std::lower_bound(v.begin(),v.end(),3), std::upper_bound(v.begin(),v.end(),3)) == 2 // 3 is present
    
  • 将迭代器指向的元素与您的值进行比较(假设运算符!=< 是一致的),但您必须确保它不会返回结束迭代器。

    *(std::lower_bound(v.begin(), v.end(), 5)) != 5
    

此外,由于lower_bound 是一种二分搜索算法,如果未找到该元素,则返回end 将是不一致的。实际上,该算法返回的迭代器可以作为后续插入操作的提示。

【讨论】:

  • +1:但正如迈耶斯在那本书中所说,比较平等并不总是有效(因为lower_bound 使用<,而不是==)。
  • @Oli Charlesworth:如果你覆盖<,你可能也应该覆盖==。改编答案。
  • 即使你这样做,它们也不一定对应:==对应“平等”,<对应“等价”。有关此问题的讨论,请参阅有效 STL 的第 19 条。
  • 如果你重载<,你也应该以兼容的方式重载==(和<=>>=!=)。真正的问题是当您不重载<,而是将比较运算符传递给lower_bound 时。在这种情况下,您必须在调用lower_bound 后进行检查时使用相同的比较函数。
猜你喜欢
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 2016-03-18
  • 2019-11-20
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多