c++ - binary_search、find_if 和 <functional>

标签 c++ stl std

std::find_if 在其重载函数之一中采用谓词。绑定(bind)器使得为用户定义的类型编写 EqualityComparators 并将它们用于动态比较或静态比较成为可能。

相比之下,标准库的二进制搜索函数采用比较器和 const T& 来比较应该用于比较的值。这对我来说感觉不一致,并且可能效率更低,因为每次都必须使用两个参数调用比较器,而不是将常量参数绑定(bind)到它。虽然有可能以使用 std::bind 的方式实现 std::binary_search,但这需要所有比较器都继承自 std::binary_function。我见过的大多数代码都不会这样做。

当将比较器与以 const T& 为值的算法一起使用时,让比较器从 std::binary_function 继承而不是让我使用 Binder ?是否有理由不在这些函数中提供谓词重载?

最佳答案

std::binary_search 的单参数谓词版本无法在 O(log n) 时间内完成。

想一想“猜猜我想到的字母”这个老游戏。你可以问:“是 A 吗?” “是 B 吗?”.. 依此类推,直到找到字母。这是一个线性或 O(n) 算法。但更聪明的做法是问“它在 M 之前吗?” “是在G之前吗?” “是在我之前吗?”依此类推,直到找到有问题的字母。这是一个对数或 O(log n) 算法。

这就是std::binary_search确实如此,要做到这一点需要能够区分三个条件:

  • 候选C是搜索的项目X
  • 候选C大于X
  • 候选C小于X

单参数谓词 P(x) 仅表示“x 具有属性 P”或“x 不具有属性 P”。您无法从此 bool 函数获得三个结果。

比较器(比如 <)让您通过计算 C < X 和 X < C 得到三个结果。然后您有三种可能性:

  • !(C < X) && !(X < C) C等于X
  • C < X && !(X < C) C小于X
  • !(C < X) && X < C C大于X

请注意,X 和 C 都绑定(bind)到 < 的两个参数在不同的时间,这就是为什么你不能只将 X 绑定(bind)到 < 的一个参数并使用它。

编辑:感谢 jpalecek 提醒我 binary_search 使用 <,而不是 <=。 编辑编辑:感谢 Rob Kennedy 的澄清。

关于c++ - binary_search、find_if 和 <functional>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2371833/

相关文章:

c++ - Qt 5 : CONFIG+=c++11 vs QMAKE_CXXFLAGS+=-std=c++11 (What's better)

c++11 uint64_t 循环的原子递减为 0

C++ - 检查指针是否指向有效内存(此处不能使用 NULL 检查)

c++ - std::map 插入段错误

c++ - 关于 std::vector 的两个简短问题

c++ - std string vs char performance,从一开始就删除部分的最佳技术

c++ - if (!x) 和 if (x == nullptr) 之间有什么区别吗?

c++ - 下限 == 上限

c++ - 为什么我使用 STL sort() 获得二次时间排序?

c++ - 如何传递用户数据来比较 std::sort 的功能?