Namespaces
Variants

std:: partition_point

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
partition_point
(C++11)

Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Определено в заголовочном файле <algorithm>
template < class ForwardIt, class UnaryPred >
ForwardIt partition_point ( ForwardIt first, ForwardIt last, UnaryPred p ) ;
(начиная с C++11)
(constexpr начиная с C++20)

Исследует разделённый диапазон [ first , last ) и находит конец первого раздела, то есть первый элемент, который не удовлетворяет p или last если все элементы удовлетворяют p .

Если элементы elem в диапазоне [ first , last ) не являются разделёнными относительно выражения bool ( p ( elem ) ) , поведение не определено.

Содержание

Параметры

first, last - пара итераторов, определяющих разделённый диапазон элементов для проверки
p - унарный предикат, который возвращает ​ true для элементов, найденных в начале диапазона.

Выражение p ( v ) должно быть преобразуемо в bool для каждого аргумента v типа (возможно const) VT , где VT - это тип значения ForwardIt , независимо от категории значения , и не должно изменять v . Таким образом, параметр типа VT & не допускается , как и VT , за исключением случаев, когда для VT перемещение эквивалентно копированию (since C++11) . ​

Требования к типам
-
ForwardIt должен удовлетворять требованиям LegacyForwardIterator .
-
UnaryPred должен удовлетворять требованиям Predicate .

Возвращаемое значение

Итератор, указывающий за конец первой части в диапазоне [ first , last ) или last если все элементы удовлетворяют p .

Сложность

Дано N как std:: distance ( first, last ) , выполняет O(log(N)) применений предиката p .

Примечания

Этот алгоритм является более общей формой std::lower_bound , который может быть выражен через std::partition_point с предикатом [ & ] ( const auto & e ) { return e < value ; } ) ; .

Возможная реализация

template<class ForwardIt, class UnaryPred>
constexpr //< since 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)
проверяет, отсортирован ли диапазон в порядке возрастания
(шаблон функции)
возвращает итератор к первому элементу не меньшему заданного значения
(шаблон функции)
находит точку разбиения разделённого диапазона
(функциональный объект алгоритма)