C++. STL. Алгоритмы. Алгоритмы обмена значениями элементов последовательности

Модифицирующие алгоритмы. Часть 2
Алгоритмы обмена значениями элементов последовательности


Содержание


Поиск на других ресурсах:

1. Алгоритм swap. Обмен значениями двух переменных (объектов)

Для обмена значениями двух объектов или массивов используется алгоритм swap. Алгоритм имеет несколько реализаций, наиболее распространенные из которых следующие

template <class Type>
void swap(
  Type& left,
  Type& right);
  template <class Type, size_t N>
  void swap(
  Type (& left)[N],
  Type (& right)[N]);

здесь

  • left, right – объекты, значение которых нужно обменять местами;
  • N – размер массивов объектов.

Пример.

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

int main()
{
  // Алгоритм swap - обмен значениями
  // 1. Обмен типов int
  int a = 8, b = 9;
  swap(a, b);
  cout << "a = " << a << ", b = " << b << endl; // a = 9, b = 8

  // 2. Обмен массивов фиксированного размера
  int A1[] = { 1, 5, 3 };
  int A2[] = { 2, 8, 4 };

  swap(A1, A2);

  cout << "A1 => ";
  for (int i : A1)
    cout << i << " ";
  cout << endl;

  cout << "A2 => ";
  for (int i : A2)
    cout << i << " ";
  cout << endl;

  // 3. Обмен значениями указателей unique_ptr<T>
  unique_ptr<int> p1(new int(38));
  unique_ptr<int> p2(new int(29));
  swap(p1, p2);
  cout << "p1->" << *p1 << endl;
  cout << "p2->" << *p2 << endl;

  // 4. Обмен значениями указателей shared_ptr<T>
  shared_ptr<int> ps1(new int(100));
  shared_ptr<int> ps2(new int(50));
  swap(ps1, ps2);
  cout << "ps1->" << *ps1 << endl;
  cout << "ps2->" << *ps2 << endl;

  // 5. Обмен значениями векторов
  vector<int> v1 = { 1, 3, 8, 4 };
  vector<int> v2 = { 7, 9, 0 };
  swap(v1, v2);
  cout << "v1 => ";
  for (int i : v1)
    cout << i << " ";
  cout << endl;
  cout << "v2 => ";
  for (int i : v2)
    cout << i << " ";
  cout << endl;
}

Результат

a = 9, b = 8
A1 => 2 8 4
A2 => 1 5 3
p1->29
p2->38
ps1->50
ps2->100
v1 => 7 9 0
v2 => 1 3 8 4

 

2. Алгоритм swap_ranges. Обменять местами диапазоны элементов двух последовательностей

Алгоритм swap_ranges меняет местами элементы двух диапазонов. Наиболее распространенная реализация алгоритма имеет следующий вид

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator2 swap_ranges(
  ForwardIterator1 first1,
  ForwardIterator1 last1,
  ForwardIterator2 first2 );

здесь

  • first1, last1 – прямые итераторы, задающие первый диапазон элементов;
  • first2 – прямой итератор, задающий начало второго диапазона элементов.

Пример.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм swap_ranges - меняет местами элементы заданного диапазона

  // 1. Объявить 2 вектора и вывести их на экран
  vector<char> V1 = { 'a', 'b', 'c', 'd', 'e', 'f' };
  vector<char> V2 = { '0', '1', '2', '3', '4' };

  cout << "V1 => ";
  for (char c : V1)
    cout << c << " ";
  cout << endl;

  cout << "V2 => ";
  for (char c : V2)
    cout << c << " ";
  cout << endl;
  cout << "-------------------" << endl;

  // 2. Создать итераторы на начало и конец диапазона вектора V1
  vector<char>::iterator itBegin = V1.begin();
  vector<char>::iterator itEnd = V1.begin();
  itEnd++;
  itEnd++; // itEnd -> 'c'

  // 3. Создать итераторы на начало и конец диапазона вектора V2
  vector<char>::iterator itBegin2 = V2.begin();
  itBegin2 += 3; // itBegin2 -> '3'

  // 4. Вызов алгоритма
  swap_ranges(itBegin, itEnd, itBegin2);

  // 5. Вывести вектор V1
  cout << "V1 => ";
  for (char c : V1)
    cout << c << " ";
  cout << endl;

  // 6. Вывести вектор V2
  cout << "V2 => ";
  for (char c : V2)
    cout << c << " ";
  cout << endl;
}

Результат

V1 => a b c d e f
V2 => 0 1 2 3 4
-------------------
V1 => 3 4 c d e f
V2 => 0 1 2 a b

 

3. Алгоритм iter_swap. Обмен местами двух значений, на которые указывают итераторы

Алгоритм iter_swap производит обмен местами двух значений, на которые указывают итераторы. Согласно документации, шаблон алгоритма следующий

template <class ForwardIterator1, class ForwardIterator2>
void iter_swap( ForwardIterator1 left, ForwardIterator2 right );

здесь

  • left – итератор на первое значение (значение, размещаемое слева);
  • right – итератор на второе значение (значение, размещаемое справа).

Пример.

#include <iostream>
#include <queue>
#include <vector>
#include <list>
#include <functional>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм iter_swap - меняет местами два значения, на которые указывают итераторы

  // 1. Объявить вектор
  vector<double> V1 = { 1.1, 2.2, 2.7, 2.8, 3.2 };

  // 2. Вывести вектор
  cout << "V1 => ";
  for (double x : V1)
    cout << x << " ";
  cout << endl;

  // 3. Установить итераторы на первый и последний элемент вектора
  vector<double>::iterator it1 = V1.begin();
  vector<double>::iterator it2 = V1.begin();
  while (it2 != V1.end()) it2++;
  it2--;

  // 4. Обменять местами - алгоритм iter_swap
  iter_swap(it1, it2);

  // 5. Повторно вывести вектор V1
  cout << "V1 => ";
  for (double x : V1)
    cout << x << " ";
  cout << endl;
}

Результат

V1 => 1.1 2.2 2.7 2.8 3.2
V1 => 3.2 2.2 2.7 2.8 1.1

 


Связанные темы