std::rotate
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, |
(2) | (desde C++17) |
std::rotate
intercambia los elementos en el rango [
first,
last)
de tal manera que los elementos en [
first,
middle)
se colocan después de los elementos en [
middle,
last)
mientras que se conserva el orden de los elementos en ambos rangos.Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
-
[
first,
middle)
o[
middle,
last)
no es un rango válido.
|
(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) | |
(C++20) |
Rota el orden de los elementos en un rango. (niebloid) |