std::partition_point
来自cppreference.com
在标头 <algorithm> 定义
|
||
template< class ForwardIt, class UnaryPred > ForwardIt partition_point( ForwardIt first, ForwardIt last, UnaryPred p ); |
(C++11 起) (C++20 起为 constexpr ) |
|
检验(如同用 std::partition)已划分范围 [
first,
last)
,并定位第一分段的结尾,即首个不满足 p 的元素,或者在所有元素满足 p 时是 last。
如果 [
first,
last)
的元素 elem 没有按表达式 bool(p(elem)) 划分,那么行为未定义。
参数
first, last | - | 要检验的已划分元素范围 |
p | - | 对于在范围起始找到的元素则返回 true 的一元谓词。 对每个(可为 const 的) |
类型要求 | ||
-ForwardIt 必须满足老式向前迭代器 (LegacyForwardIterator) 。
| ||
-UnaryPred 必须满足谓词 (Predicate) 。
|
返回值
[
first,
last)
内第一分段结尾后的迭代器。
复杂度
给定 N 为 std::distance(first, last),应用 O(log(N)) 次谓词 p。
注解
此算法是 std::lower_bound 的更通用化的形式,它可以表达为以 [&](const auto& e) { return e < value; }); 为谓词调用 std::partition_point
。
可能的实现
template<class ForwardIt, class UnaryPred> constexpr //< C++20 起 ForwardIt partition_point(ForwardIt first, ForwardIt last, UnaryPred p) { for (auto length = std::distance(first, last); 0 < length; ) { auto half = length / 2; auto middle = std::next(first, half); if (p(*middle)) { first = std::next(middle); length -= (half + 1); } else length = half; } return first; } |
示例
运行此代码
#include <algorithm> #include <array> #include <iostream> #include <iterator> auto print_seq = [](auto rem, auto first, auto last) { for (std::cout << rem; first != last; std::cout << *first++ << ' ') {} std::cout << '\n'; }; int main() { std::array v{1, 2, 3, 4, 5, 6, 7, 8, 9}; auto is_even = [](int i) { return i % 2 == 0; }; std::partition(v.begin(), v.end(), is_even); print_seq("划分后,v:", v.cbegin(), v.cend()); const auto pp = std::partition_point(v.cbegin(), v.cend(), is_even); const auto i = std::distance(v.cbegin(), pp); std::cout << "划分点在 " << i << ";v[" << i << "] = " << *pp << '\n'; print_seq("第一分段(所有偶数元素):", v.cbegin(), pp); print_seq("第二分段(所有奇数元素):", pp, v.cend()); }
可能的输出:
划分后,v:8 2 6 4 5 3 7 1 9 划分点在 4;v[4] = 5 第一分段(所有偶数元素):8 2 6 4 第二分段(所有奇数元素):5 3 7 1 9
参阅
(C++11) |
寻找首个满足特定判别标准的元素 (函数模板) |
(C++11) |
检查范围是否已按升序排列 (函数模板) |
返回指向第一个不小于 给定值的元素的迭代器 (函数模板) | |
(C++20) |
定位已划分范围的划分点 (niebloid) |