◐ Shell
clean mode source ↗

std::ranges::adjacent_find - cppreference.com

De cppreference.com

Definido en el archivo de encabezado <algorithm>

Signatura de la llamada

template< std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, std::indirect_binary_predicate< std::projected<I, Proj>, std::projected<I, Proj>> Pred = ranges::equal_to > constexpr I adjacent_find( I first, S last, Pred pred = {}, Proj proj = {} );

(1) (desde C++20)

template< ranges::forward_range R, class Proj = std::identity, std::indirect_binary_predicate< std::projected<ranges::iterator_t<R>, Proj>, std::projected<ranges::iterator_t<R>, Proj>> Pred = ranges::equal_to > constexpr ranges::borrowed_iterator_t<R> adjacent_find( R&& r, Pred pred = {}, Proj proj = {} );

(2) (desde C++20)

Busca en el rango [firstlast) por dos elementos consecutivos iguales.

1) Los elementos se comparan usando pred (después de proyectar con la proyección proj).

2) Igual que (1), pero usa r como el rango fuente, como si usara ranges::begin(r) como first y ranges::end(r) como last.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

first, last - El rango de los elementos a examinar.
r - El rango de los elementos a examinar.
pred - El predicado a aplicar a los elementos proyectados.
proj - La proyección a aplicar a los elementos.

Valor de retorno

Un iterador al primer elemento del primer par de elementos idénticos; es decir, al primer iterador it tal que bool(std::invoke(pred, std::invoke(proj1, *it), std::invoke(proj, *(it + 1)))) es true.

Si tales elementos no se encuentran, se devuelve un iterador igual a last.

Complejidad

Exactamente min((result - first) + 1, (last - first) - 1) aplicaciones del predicado y proyección, donde result es el valor de retorno.

Posible implementación

struct adjacent_find_fn
{
    template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity,
             std::indirect_binary_predicate<
                 std::projected<I, Proj>,
                 std::projected<I, Proj>> Pred = ranges::equal_to>
    constexpr I operator()(I first, S last, Pred pred = {}, Proj proj = {}) const
    {
        if (first == last)
            return first;
        auto next = ranges::next(first);
        for (; next != last; ++next, ++first)
            if (std::invoke(pred, std::invoke(proj, *first), std::invoke(proj, *next)))
                return first;
        return next;
    }

    template<ranges::forward_range R, class Proj = std::identity,
             std::indirect_binary_predicate<
                 std::projected<ranges::iterator_t<R>, Proj>,
                 std::projected<ranges::iterator_t<R>, Proj>> Pred = ranges::equal_to>
    constexpr ranges::borrowed_iterator_t<R>
        operator()(R&& r, Pred pred = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj));
    }
};

inline constexpr adjacent_find_fn adjacent_find;

Ejemplo

#include <algorithm>
#include <functional>
#include <iostream>

int main()
{
    const auto v = {0, 1, 2, 3, 40, 40, 41, 41, 5}; /*
                                ^^          ^^       */
    namespace ranges = std::ranges;

    if (auto it = ranges::adjacent_find(v.begin(), v.end()); it == v.end())
        std::cout << "No hay elementos adyacentes coincidentes\n";
    else
        std::cout << "El primer par adyacente de elementos iguales se encuentra en ["
                  << ranges::distance(v.begin(), it) << "] == " << *it << '\n';

    if (auto it = ranges::adjacent_find(v, ranges::greater()); it == v.end())
        std::cout << "Todo el vector está ordenado en orden ascendente\n";
    else
        std::cout << "El último elemento en una subsecuencia no decreciente se encuentra en ["
                  << ranges::distance(v.begin(), it) << "] == " << *it << '\n';
}

Salida:

El primer par adyacente de elementos iguales se encuentra en [4] == 40
El último elemento en una subsecuencia no decreciente se encuentra en [7] == 41

Véase también

Elimina elementos duplicados consecutivos en un rango.
(niebloid) [editar]
Encuentra dos elementos contiguos idénticos (o que satisfagan un predicado dado).
(plantilla de función) [editar]