C++. STL. Алгоритмы обрабатывающие последовательность в целом

Алгоритмы обрабатывающие последовательность в целом не изменяя значений элементов (реверсирование, циклическое смещение, копирование, перемешивание)


Содержание


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

1. Алгоритм copy. Копирует одну последовательность в другую. Пример для классов vector, list
Алгоритм copy реализует копирование одной последовательности в другую. Распространенная реализация имеет следующее объявление
template<class InputIterator, class OutputIterator>
OutputIterator copy(
    InputIterator first,
    InputIterator last,
    OutputIterator destBeg);
здесь
  • first, last – итераторы ввода, реализующие диапазон чисел, который нужно скопировать;
  • destBeg – итератор вывода, определяющий начало диапазона, в который копируется исходный диапазон.
Пример.
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;

void main()
{
  // Алгоритм copy
  // 1. Демонстрация для класса vector
  // 1.1. Создать список инициализации
  initializer_list<double> IL1 = { 2.8, 3.5, 1.4, 2.9, 7.3 };

  // 1.2. Создать экземпляр vector на основе списка L1
  vector<double> V1(IL1);

  // 1.3. Создать новый массив-приемник, в этом массив будет копироваться массив V1
  vector<double> V2(V1.size()); // обязательно нужно выделить память в V2

  // 1.4. Скопировать V1 => V2, использовать алгоритм copy
  copy(V1.begin(), V1.end(), V2.begin());

  // 1.5. Вывести массив V2
  cout << "V2 => ";
  for (double t : V2)  // цикл в стиле foreach
    cout << t << "  ";
  cout << endl;

  // ---------------------------------------
  // 2. Демонстрация для класса list
  // 2.1. Создать массив-источник
  initializer_list<int> IL2 = { 2, 3, 8, 1, 4, 9 };
  list<int> L1(IL2);

  // 2.2. Создать массив-приемник
  list<int> L2(L1.size());

  // 2.3. Скопировать lst2 <= lst1
  copy(L1.begin(), L1.end(), L2.begin());

  // 2.4. Вывести lst2 с помощью итератора
  list<int>::iterator it = L2.begin();
  cout << "L2 => ";
  while (it != L2.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}
Результат
V2 => 2.8  3.5  1.4  2.9  7.3
L2 => 2 3 8 1 4 9

 

2. Алгоритм copy_backward. Копирует последовательность в обратном порядке
Алгоритм copy_backward выполняет копирование последовательности из исходного диапазона в диапазон назначения в обратном порядке. Объявление алгоритма следующее
template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 copy_backward(
    BidirectionalIterator1 first,
    BidirectionalIterator1 last,
    BidirectionalIterator2 destEnd);
здесь
  • first, last – двунаправленные итераторы, указывающие начало и конец исходного диапазона;
  • destEnd – двунаправленный итератор, указывающий на начало диапазона-назначения.
Пример.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

void main()
{
  // Алгоритм copy_backward – копировать данные в обратном порядке.
  // Использование для класса vector
  // 1. Создать массив на основе списка инициализации
  initializer_list<int> IL = { 2, 3, 8, 1, 6 };
  vector<int> V(IL);

  // 2. Создать новый массив на основе размера первого
  vector<int> V2(V.size());

  // 3. Вызвать алгоритм copy_backward,
  //    данные в вектор V2 копируются с конца.
  copy_backward(V.begin(), V.end(), V2.end());

  // 4. Вывести массив V2
  vector<int>::iterator it = V2.begin();
  while (it != V2.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}
Результат
2 3 8 1 6

 

3. Алгоритм reverse. Изменить порядок элементов на противоположный (реверсирование)
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <time.h>
#include <list>
using namespace std;

int main()
{
  // Алгоритм reverse – изменить порядок элементов на противоположный (реверсирование)
  // 1. Создать массив чисел
  vector<double> V = { 2.8, 3.3, 4.5, 1.7, 2.9 };

  // 2. Реверсировать массив V - алгоритм reverse
  reverse(V.begin(), V.end());

  // 3. Вывести реверсированный массив
  for (int i = 0; i < V.size(); i++)
    cout << V[i] << " ";
  cout << endl;
}
Результат
2.9 1.7 4.5 3.3 2.8

 

4. Алгоритм reverse_copy. Реверсировать массив с получением копии
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <time.h>
#include <list>
using namespace std;

int main()
{
  // Алгоритм reverse_copy - реверсировать массив с получением копии
  // 1. Создать массив чисел
  vector<double> V1 = { 1.1, 2.2, 3.3, 4.4, 5.5 }; // массив-оригинал
  vector<double> V2(V1.size()); // массив-копия - задать размер массива (обязательно)

  // 2. Реверсировать массив V1 с получением копии V3 – алгоритм reverse_copy
  reverse_copy(V1.begin(), V1.end(), V2.begin());

  // 3. Вывести массив-оригинал
  cout << "V1 => ";
  vector<double>::iterator it = V1.begin();
  while (it != V1.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 4. Вывести массив-копию
  cout << "V2 => ";
  it = V2.begin();
  while (it != V2.end())
  {
    cout << *it << " ";
    it++;
  }
}
Результат
V1 => 1.1 2.2 3.3 4.4 5.5
V2 => 5.5 4.4 3.3 2.2 1.1

 

5. Алгоритм rotate. Циклическое смещение в заданных пределах
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм rotate – циклический сдвиг влево в заданных пределах
  // 1. Створити масив чисел
  vector<double> V1 = { 1.1, 2.2, 3.3, 4.4, 5.5 }; // массив-оригинал

  // 2. Задать точку, к которой будет происходить смещение,
  //    эта точка в пределах от V1.begin() до V1.end()
  vector<double>::iterator it = V1.begin();

  it++; // следующая точка после V1.begin() - это позиция 2.2

  // 3. Осуществить смещение всего вектора к этой точке - алгоритм rotate
  rotate(V1.begin(), it, V1.end());

  // 4. Вывести массив-оригинал
  cout << "V1 => ";
  it = V1.begin();
  while (it != V1.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}
Результат
V1 => 2.2 3.3 4.4 5.5 1.1

 

6. Алгоритм rotate_copy. Циклический сдвиг с получением копии последовательности
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм rotate_copy - циклический сдвиг с получением копии последовательности
  // 1. Создать массив чисел
  vector<double> V1 = { 1.1, 2.2, 3.3, 4.4, 5.5 }; // массив-оригинал
  vector<double> V2(V1.size());

  // 2. Задать точку, в которую будет происходить смещение,
  //    эта точка в пределах от V1.begin() до V1.end()
  vector<double>::iterator it = V1.begin();
  it++;
  it++; // установить итератор на позицию 3.3

  // 3. Осуществить сдвиг всего вектора к этой точке – алгоритм rotate_copy
  rotate_copy(V1.begin(), it, V1.end(), V2.begin());

  // 4. Вывести массив-копию
  cout << "V2 => ";
  it = V2.begin();
  while (it != V2.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}
Результат
V2 => 3.3 4.4 5.5 1.1 2.2

 

7. Алгоритм random_shuffle (заменен на shuffle). Перемешать последовательность случайным образом
#include <iostream>
#include <queue>
#include <vector>
#include <list>
#include <functional>
#include <algorithm>
using namespace std;

int main()
{
  // Алгоритм random_shuffle - перемешивание (переупорядочение) элементов последовательности
  // 1. Использование алгоритма без предиката
  // 1.1. Объявить вектор и сформировать его
  vector<float> V1;

  for (int i = 0; i < 10; i++)
    V1.push_back(i * 1.0f);

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

  // 1.3. Перемешать элементы
  random_shuffle(V1.begin(), V1.end());

  // 1.4. Повторно вывести вектор
  cout << "V1 => ";
  for (float x : V1)
    cout << x << "  ";
  cout << endl;
}
Результат
V1 => 0  1  2  3  4  5  6  7  8  9
V1 => 8  1  9  2  0  5  7  3  4  6

 


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