Espacios de nombres
Variantes
Acciones

std::rotate

De cppreference.com
< cpp‎ | algorithm
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Definido en el archivo de encabezado <algorithm>
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt middle, ForwardIt last );
(1) (constexpr desde C++20)
template< class ExecutionPolicy, class ForwardIt >

ForwardIt rotate( ExecutionPolicy&& policy,

                  ForwardIt first, ForwardIt middle, ForwardIt last );
(2) (desde C++17)
1) Realiza una rotación hacia la izquierda en un rango de elementos.
Específicamente, std::rotate intercambia los elementos en el rango [firstlast) de tal manera que los elementos en [firstmiddle) se colocan después de los elementos en [middlelast) mientras que se conserva el orden de los elementos en ambos rangos.
2) Igual que (1), pero ejecutado de acuerdo con la política de ejecución policy.
Esta sobrecarga no participa en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.

Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:

(hasta C++11)
(desde C++11)

Contenido

[editar] Parámetros

first, last - El par de iteradores que definen el rango de elementos a rotar
middle - El elemento que debe aparecer al principio del rango rotado.
policy - La política de ejecución a usar. Véase política de ejecución para más detalles.
Requisitos de tipo
-
ForwardIt debe satisfacer los requisitos de IteradorDeAvanceLegado.

[editar] Valor de retorno

El iterador del elemento al que hace referencia originalmente *first, es decir, el siguiente iterador std::distance(middle, last)
ésimo
de first.

[editar] Complejidad

Como máximo, std::distance(first, last) intercambios.

[editar] Excepciones

La sobrecarga con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reporta errores tales que:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.

[editar] Posible implementación

Véase también las implementaciones en libstdc++, libc++, y MSVC STL.

template<class ForwardIt>
constexpr // desde C++20
ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last)
{
    if (first == middle)
        return last;
 
    if (middle == last)
        return first;
 
    ForwardIt write = first;
    ForwardIt next_read = first; // posición de lectura para cuando “read” llegue a “last”
 
    for (ForwardIt read = middle; read != last; ++write, ++read)
    {
        if (write == next_read)
            next_read = read; // rastrear dónde quedó “first”
        std::iter_swap(write, read);
    }
 
    // rotar la secuencia restante en su lugar
    rotate(write, next_read, last);
    return write;
}

[editar] Notas

std::rotate tiene mejor eficiencia en implementaciones comunes si ForwardIt satisface IteradorBidireccionalLegado o (mejor) IteradorDeAccesoAleatorioLegado.

Las implementaciones (p. ej., MSVC STL) pueden habilitar la vectorización cuando el tipo iterador satisface IteradorContiguoLegado y el intercambio de su tipo valor no llama a una función miembro especial no trivial ni a swap hallada por la búsqueda dependiente de argumento.

[editar] Ejemplo

std::rotate es un componente básico común en muchos algoritmos. Este ejemplo demuestra ordenamiento por inserción.

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
 
auto print = [](const auto remark, const auto& v)
{
    std::cout << remark;
    for (auto n : v)
        std::cout << std::setw(2) << n << ' ';
    std::cout << '\n';
};
 
int main()
{
    std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1};
    print("antes del ordenamiento:         ", v);
 
    // ordenamiento por inserción
    for (auto i = v.begin(); i != v.end(); ++i)
        std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1);
    print("después del ordenamiento:       ", v);
 
    // rotación simple a la izquierda
    std::rotate(v.begin(), v.begin() + 1, v.end());
    print("rotación simple a la izquierda: ", v);
 
    // rotación simple a la derecha
    std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
    print("rotación simple a la derecha:   ", v);
}

Salida:

antes del ordenamiento:          2  4  2  0  5 10  7  3  7  1 
después del ordenamiento:        0  1  2  2  3  4  5  7  7 10 
rotación simple a la izquierda:  1  2  2  3  4  5  7  7 10  0 
rotación simple a la derecha:    0  1  2  2  3  4  5  7  7 10

[editar] Informes de defectos

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.

ID Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 488 C++98 No se devolvía la nueva ubicación del elemento al que apunta first. Se devuelve.

[editar] Véase también

Copia y rota un rango de elementos.
(plantilla de función) [editar]
Rota el orden de los elementos en un rango.
(niebloid) [editar]