std::ranges::partition_point
在标头 <algorithm> 定义 | ||
调用签名 | ||
template<std::forward_iterator I, std::sentinel_for<I> S, class Proj =std::identity, | (1) | (C++20 起) |
template<ranges::forward_range R, class Proj =std::identity, | (2) | (C++20 起) |
检验已划分(如同用 ranges::partition)范围 [
first,
last)
或 r 并定位第一划分的结尾,即不满足 pred 的被投影元素,或若所有投影后元素均满足 pred 则为 last。
此页面上描述的函数式实体是算法函数对象(非正式地称为 niebloid),即:
目录 |
[编辑]参数
first, last | - | 要检验的部分有序元素范围的迭代器-哨位对 |
r | - | 要检验的部分有序范围 |
pred | - | 应用到投影后元素的谓词 |
proj | - | 应用到元素的投影 |
[编辑]返回值
[
first,
last)
内第一划分的尾后位置迭代器,或若所有投影后元素均满足 pred 则为等于 last 的迭代器。
[编辑]复杂度
给定 N =ranges::distance(first, last),应用 O(log N) 次谓词 pred 与投影 proj。
然而,若哨位不实现 std::sized_sentinel_for<I>,则迭代器自增次数为 O(N)。
[编辑]注解
此算法是 ranges::lower_bound
的更通用的形式,能用 ranges::partition_point
用 [&](autoconst& e){returnstd::invoke(pred, e, value);}); 为谓词表达它。
[编辑]示例
#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::ranges::partition(v, is_even); print_seq("After partitioning, v: ", v.cbegin(), v.cend()); constauto pp = std::ranges::partition_point(v, is_even);constauto i = std::ranges::distance(v.cbegin(), pp);std::cout<<"Partition point is at "<< i <<"; v["<< i <<"] = "<<*pp <<'\n'; print_seq("First partition (all even elements): ", v.cbegin(), pp); print_seq("Second partition (all odd elements): ", pp, v.cend());}
可能的输出:
After partitioning, v: 2 4 6 8 5 3 7 1 9 Partition point is at 4; v[4] = 5 First partition (all even elements): 2 4 6 8 Second partition (all odd elements): 5 3 7 1 9
[编辑]参阅
(C++20) | 检查范围是否已按升序排列 (算法函数对象) |
(C++20) | 返回首个不小于 给定值的元素的迭代器 (算法函数对象) |
(C++11) | 定位已划分范围的划分点 (函数模板) |