How do I reverse a C++ vector?
Is there a built-in vector function in C++ to reverse a vector in place?
Or do you just have to do it manually?
5 Answers 5
There’s a function std::reverse in the algorithm header for this purpose.
All containers offer a reversed view of their content with rbegin() and rend() . These two functions return so-calles reverse iterators, which can be used like normal ones, but it will look like the container is actually reversed.
You can use std::reverse like this
Often the reason you want to reverse the vector is because you fill it by pushing all the items on at the end but were actually receiving them in reverse order. In that case you can reverse the container as you go by using a deque instead and pushing them directly on the front. (Or you could insert the items at the front with vector::insert() instead, but that would be slow when there are lots of items because it has to shuffle all the other items along for every insertion.) So as opposed to:
Обратные векторные элементы с помощью утилит STL в C++

В этой статье будет рассказано, как реверсировать векторные элементы с помощью утилит STL на C++.
Используйте алгоритм std::reverse для обратного преобразования векторных элементов в C++
std::reverse является частью алгоритмов STL и может использоваться для изменения порядка элементов в любом заданном диапазоне. Алгоритм std::reverse внутренне меняет местами два элемента, начиная с первой и последней пары. std::reverse принимает два аргумента, которые представляют итераторы данного диапазона. В следующем примере мы генерируем случайные целые числа как объект vector, который меняет местами с помощью алгоритма std::reverse и выводит результаты в поток cout.
Используйте алгоритм std::shuffle для случайного изменения порядка элементов вектора в C++
std::shuffle может использоваться для случайного изменения порядка элементов в диапазоне таким образом, чтобы каждая перестановка элементов имела равную вероятность. Функция принимает как минимум два аргумента, которые обозначают начальный и конечный итераторы диапазона. Необязательно, std::shuffle может принимать третий аргумент, представляющий функцию генератора случайных чисел. В этом случае мы использовали mersenne_twister_engine, который указан в заголовке <random> .
Используйте алгоритм std::rotate для поворота элементов вектора в C++
Еще одна полезная функция, включенная в алгоритмы STL — std::rotate . Функция сдвигает элементы влево и оборачивает элементы, которые перемещаются за пределы границы вектора. std::rotate принимает три аргумента итератора типа ForwardIt и выполняет вращение, так что элемент, на который указывает второй аргумент, перемещается в первую позицию вновь сгенерированного списка.
Как перевернуть вектор в C++?

Программирование и разработка
Если вектор имеет элементы в последовательности, <’A’, ’B’, ’C’, ’D’, ’E’>, и он переконфигурируется так, что его последовательность становится, <’E’, ’D’, ’ C ’,’ B ’,’ A ’>, то вектор был перевернут. К сожалению, в C ++ такая прямая обратимость невозможна. Однако вектор в C ++ может повторяться сзади, и это косвенная обратимость. При этом нет необходимости буквально переворачивать вектор. В этой статье объясняется, как выполнить итерацию вектора в C ++ с обратной стороны и изменить его элементы.
Перед использованием вектора в C ++ программа должна начинаться с,
с включенной векторной библиотекой. Обратную итерацию легче понять, если составить сводку пересылки итерации. Таким образом, перед объяснением обратной итерации сначала резюмируется прямая итерация.
Прямая итерация
Прямая итерация имеет дело с двумя итераторами. Итератор — это тщательно продуманный объект-указатель со специальными характеристиками. Здесь два интересующих нас итератора возвращаются функцией-членом begin () и функцией-членом end (). Функция-член begin () возвращает итератор, указывающий на первый элемент вектора. Функция-член end () возвращает итератор, который указывает сразу за последним элементом вектора.
Предположим, что имя вектора — vtr, тогда следующий оператор вернет начальный итератор:
где p — имя начального итератора. Следующий оператор вернет конечный итератор:
где q — это имя, данное конечному итератору, из двух приведенных выше операторов видно, что p и q имеют один и тот же тип и даже могут быть заменены местами.
Все фрагменты кода для этой статьи написаны в функции main (). Следующий код считывает все элементы вектора от начала до последнего:
Код в круглых скобках цикла for требует пояснения. p — итератор, который сначала указывает на первый элемент вектора. Хотя он еще не указывает только за пределы вектора, он увеличивается на p ++, чтобы указать на каждый элемент в векторе. Когда он указывает на элемент в векторе, значение (символ) элемента получается с помощью * p в теле цикла for. * — косвенный оператор.
Следующий код считывает и отображает значения в векторе от последнего элемента до первого элемента, используя конечный итератор:
Конечный итератор указывает сразу за концом вектора, и это не элемент. Таким образом, он должен быть сначала уменьшен, прежде чем он сможет указывать на последний элемент. Оттуда итерация может идти назад.
Условие while для цикла for здесь: «если q больше или равно начальному итератору». Не может быть «если q не равно начальному итератору», так как это исключит первый элемент.
Это неформальный способ итерации в обратном направлении. То есть это неформальный способ косвенного обращения вектора.
Изменение значения элемента
Когда экземпляру вектора не предшествует const (для константы), значение любого элемента в векторе может быть изменено. Следующий код иллюстрирует это:
Конечный итератор q уменьшается три раза на «q—; q—; q—; » указать на «C».
Если экземпляру вектора предшествует константа, то значение элемента не может быть изменено. В этом случае постоянный прямой итератор должен быть возвращен для конечного или начального итератора. Следующий код не будет компилироваться, потому что сделана попытка изменить значение ’C’:
Обратная итерация
У обратной итерации есть два основных итератора. Эти итераторы возвращаются функциями-членами rbegin () и rend (). rend () возвращает итератор, который указывает прямо перед первым элементом вектора. rbegin () возвращает итератор, указывающий на последний элемент вектора. Следующий код считывает и отображает элементы вектора от первого до последнего в прямом направлении:
Используется обратный итератор. Поскольку rend () возвращает итератор, который указывает прямо перед первым элементом, который не является элементом, его необходимо увеличить, чтобы указать на первый элемент. Поскольку мы имеем дело с обратным итератором, оператор приращения здесь — а не ++. Кроме того, в условии while> = используется вместо <=.
Следующий код считывает и отображает значения в векторе от последнего элемента до первого, используя итератор rbegin ():
Функция-член rbegin () возвращает итератор, указывающий на последний элемент вектора. Возвращенный итератор — это reverse_iterator. rend () возвращает итератор, который указывает непосредственно перед первым элементом. Обратите внимание, что условие while для цикла for имеет but =, поскольку мы имеем дело с обратным итератором. Уменьшение с помощью этого итератора — ++, а не -.
Изменение значения элемента
Когда экземпляру вектора не предшествует const (для константы), значение любого элемента в векторе может быть изменено с помощью reverse_iterator. Следующий код иллюстрирует это с помощью reverse_iterator:
Итератор rbegin (), q уменьшается два раза на «q ++; q ++; » чтобы указать на ’C’, поскольку он изначально указывает на последний элемент.
Если экземпляру вектора предшествует const, то никакое значение элемента не может быть изменено с помощью итератора, будь то итератор reverse_iterator (или вперед). В этом случае постоянный обратный итератор должен быть возвращен для функции rbegin () или rend (). Следующий код не будет компилироваться, потому что сделана попытка изменить значение ’C’:
Постоянный обратный итератор
crbegin () ведет себя как rbegin (), но возвращает const_reverse_iterator независимо от того, было ли создание экземпляра вектора начато с const. Это означает, что значение возвращенного итератора изменить нельзя. crend () ведет себя как rend (), но возвращает const_reverse_iterator независимо от того, было ли создание экземпляра вектора начато с const. Это означает, что значение возвращенного итератора изменить нельзя.
Следующий код отображает все значения вектора, используя const_reverse_iterator, начиная с последнего элемента:
Следующий код не будет компилироваться, потому что здесь мы имеем дело с постоянным обратным итератором. Создание экземпляра вектора не предшествует const.
Заключение
Вектор нельзя поменять местами буквально. Однако его можно повторять от начала до конца, чтобы получить аналогичный результат. При прямой итерации задействованы функции-члены begin () и end (). В случае обратной итерации задействуются функции-члены, rbegin () и rend (). В этом случае задействованный итератор — это reverse_iterator, а не итератор. Тем не менее, в этом случае ++ — это -, а> = — это <=. Также существует const_reverse_iterator для функций-членов crbegin () и crend ().
Перевернуть вектор
Второй — это просто присвоить вектор самого себе, используя реверсивные итераторы.
А если просто надо вывести вектор в обратном порядке на консоль, то вы также можете использовать обычный цикл с реверсивными итераторами, либо с индексами, либо алгоритм std::reverse_copy
Вот демонстрационная программа, показывающая все перечисленные методы за исключением метода assign, который мог бы выглядеть следующим образом
К сожалению большинство реализаций стандартных библиотек содержат баг, и вышеуказанное предложение выполняется неверно.:)
Ее вывод на консоль:
В этой программе вызов std::reverse реверсирует сам вектор, а все остальные части программы просто выводят на консоль уже реверсированный вектор в обратном порядке