Namespaces
Variants

std::rotate

От ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Операции последовательности без изменения    
Групповые операции
(C++17)
Операции поиска
Операции последовательности с изменением
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции двоичного поиска
(по разделённым диапазонам)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определено в заголовке <algorithm>
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt middle, ForwardIt last );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt >
ForwardIt rotate( ExecutionPolicy&& policy,
                  ForwardIt first, ForwardIt middle, ForwardIt last );
(2) (начиная с C++17)
1) Выполняет левый поворот диапазона элементов.
Конкретно, std::rotate меняет местами элементы в диапазоне [first, last) таким образом, что элементы из [first, middle) помещаются после элементов из [middle, last), при этом порядок следования элементов в обоих диапазонах сохраняется.
2) То же, что (1), но выполняется в соответствии с policy.
Эта перегрузка участвует в разрешении перегрузки только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Если выполняется любое из следующих условий, поведение не определено:

  • Тип *first не является Swappable.
(до C++11)
(начиная с C++11)

Параметры

first, last - пара итераторов, определяющих диапазон элементов для ротации
middle - элемент, который должен оказаться в начале ротированного диапазона
policy - политика выполнения execution policy для использования
Требования к типам
-
ForwardIt должен удовлетворять требованиям LegacyForwardIterator .

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

Итератор на элемент, изначально ссылавшийся на * first , т.е. на std:: distance ( middle, last ) -й следующий итератор от first .

Сложность

Не более std:: distance ( first, last ) обменов.

Исключения

Перегрузка с параметром шаблона с именем ExecutionPolicy сообщает об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

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

Смотрите также реализации в libstdc++ , libc++ , и MSVC STL .

template<class ForwardIt>
constexpr // начиная с 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; // позиция чтения для случая, когда «read» достигает «last»
    for (ForwardIt read = middle; read != last; ++write, ++read)
    {
        if (write == next_read)
            next_read = read; // отслеживаем, куда переместился «first»
        std::iter_swap(write, read);
    }
    // поворачиваем оставшуюся последовательность на место
    rotate(write, next_read, last);
    return write;
}

Примечания

std::rotate обладает лучшей эффективностью в распространённых реализациях, если ForwardIt удовлетворяет требованиям LegacyBidirectionalIterator или (что предпочтительнее) LegacyRandomAccessIterator .

Реализации (например, MSVC STL ) могут использовать векторизацию, когда тип итератора удовлетворяет требованиям LegacyContiguousIterator и обмен его типа значений не вызывает ни нетривиальные специальные функции-члены, ни ADL -найденную функцию swap .

Пример

std::rotate является распространённым строительным блоком во многих алгоритмах. Этот пример демонстрирует сортировку вставками .

#include <algorithm>
#include <iostream>
#include <vector>
auto print = [](const auto remark, const auto& v)
{
    std::cout << remark;
    for (auto n : v)
        std::cout << n << ' ';
    std::cout << '\n';
};
int main()
{
    std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1};
    print("before sort:\t\t", v);
    // insertion sort
    for (auto i = v.begin(); i != v.end(); ++i)
        std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1);
    print("after sort:\t\t", v);
    // simple rotation to the left
    std::rotate(v.begin(), v.begin() + 1, v.end());
    print("simple rotate left:\t", v);
    // simple rotation to the right
    std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
    print("simple rotate right:\t", v);
}

Вывод:

before sort:		2 4 2 0 5 10 7 3 7 1
after sort:		0 1 2 2 3 4 5 7 7 10
simple rotate left:	1 2 2 3 4 5 7 7 10 0
simple rotate right:	0 1 2 2 3 4 5 7 7 10

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 488 C++98 the new location of the element pointed by first was not returned returned

См. также

копирует и поворачивает диапазон элементов
(шаблон функции & объект функции алгоритма)
поворачивает порядок элементов в диапазоне
(объект функции алгоритма)