std::ranges::partition_point

来自cppreference.com
< cpp‎ | algorithm‎ | ranges
 
 
算法库
受约束算法及范围上的算法 (C++20)
受约束算法: std::ranges::copy, std::ranges::sort, ...
执行策略 (C++17)
不修改序列的操作
(C++11)(C++11)(C++11)
(C++17)
修改序列的操作
Partitioning operations
划分操作
排序操作
(C++11)
二分搜索操作
集合操作(在已排序范围上)
堆操作
(C++11)
最小/最大操作
(C++11)
(C++17)

排列
数值运算
未初始化存储上的操作
(C++17)
(C++17)
(C++17)
C 库
 
受约束算法
不修改序列的操作
修改序列的操作
划分操作
ranges::partition_point
  
排序操作
二分搜索操作
集合操作(在已排序范围上)
堆操作
最小/最大操作
排列
未初始化存储上的操作
返回类型
 
在标头 <algorithm> 定义
调用签名
template< std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity,

          std::indirect_unary_predicate<std::projected<I, Proj>> Pred >

constexpr I partition_point( I first, S last, Pred pred, Proj proj = {} );
(1) (C++20 起)
template< ranges::forward_range R, class Proj = std::identity,

          std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> Pred >
  constexpr ranges::borrowed_iterator_t<R>

partition_point( R&& r, Pred pred, Proj proj = {} );
(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[&](auto const& e) { return std::invoke(pred, e, value); }); 为谓词表达它。

示例

#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
 
int main()
{
    std::array v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 
    namespace ranges = std::ranges;
    auto is_even = [](int i){ return i % 2 == 0; };
    ranges::partition(v, is_even);
 
    auto p = ranges::partition_point(v.begin(), v.end(), is_even);
 
    std::cout << "Before partition:\n    ";
    ranges::copy(v.begin(), p, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\nAfter partition:\n    ";
    ranges::copy(p, v.end(), std::ostream_iterator<int>(std::cout, " "));
}

输出:

Before partition:
    8 2 6 4 
After partition:
    5 3 7 1 9

参阅

检查范围是否以升序排序
(niebloid)
返回指向首个不小于给定值的元素的迭代器
(niebloid)
定位已划分范围的划分点
(函数模板)