C++. STL. Алгоритми. Алгоритми що виконують заміну елементів послідовності

Модифікуючі алгоритми. Частина 3.
Алгоритми що виконують заміну елементів послідовності


Зміст


Пошук на інших ресурсах:

1. Алгоритм replace. У заданій послідовності замінити одні значення на інші

Алгоритм replace перевіряє кожен елемент в діапазоні і замінює його, якщо він відповідає заданому значенню. Оголошення алгоритму має наступний вигляд

template <class ForwardIterator, class Type>
void replace(
  ForwardIterator first,
  ForwardIterator last,
  const Type& oldVal,
  const Type& newVal);

тут

  • first, last – прямі ітератори, які задають діапазон в якому замінюються елементи;
  • oldVal – старе значення замінюваних елементів;
  • newVal – нове значення, яке замінює значення oldVal.

Приклад.

#include <iostream>
#include <list>
#include <algorithm>
#include <time.h>
using namespace std;

void main()
{
  // Алгоритм replace - замінює одні значення на інші

  // 1. Створити список
  list<int> l;

  // Заповнити список новими значеннями 1..10
  for (int i = 0; i < 10; i++)
    l.push_back(rand() % (10 - 1 + 1) + 1);

  // 2. Вивести список для контролю
  list<int>::iterator it = l.begin();
  cout << "Old list: " << endl;
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 3. Демонстрація алгоритму replace.
  // Замінити усі числа 5 на число 0.
  replace(l.begin(), l.end(), 5, 0);

  // 4. Вивести новий список
  cout << "A new list:" << endl;
  it = l.begin();
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
}

Результат

Old list:
2 8 5 1 10 5 9 9 3 5
A new list:
2 8 0 1 10 0 9 9 3 0

 

2. Алгоритм replace_if. У послідовності замінити одні значення іншими на основі предикату або лямбда-виразу

Алгоритм replace_if здійснює перевірку кожного елементу в діапазоні, і якщо він задовільняє заданому предикату, то замінює цей елемент новим значенням.
Оголошення алгоритму наступне

template <class ForwardIterator, class UnaryPredicate, class Type>
void replace_if(
  ForwardIterator first,
  ForwardIterator last,
  UnaryPredicate pred,
  const Type& value);

тут

  • first, last – прямі ітератори, які визначають діапазон;
  • pred – унарний предикат, що задає умову виконання;
  • value – нове значення, на яке замінюється старе значення елементу у випадку якщо предикат pred стверджується.

Приклад.

#include <iostream>
#include <list>
#include <algorithm>
#include <time.h>
using namespace std;

// Предикат, який повертає true,
// якщо число знаходиться в діапазоні [3; 7]
bool Between_3_7(int value)
{
  return (3 <= value) && (value <= 7);
}

void main()
{
  // Алгоритм replace_if - замінює одні значення на інші
  // на основі предикату або лямбда-виразу

  // 1. Створити список
  list<int> l;

  // Заповнити список новими значеннями 1..10
  srand(time(NULL));
  for (int i = 0; i < 10; i++)
    l.push_back(rand() % (10 - 1 + 1) + 1);

  // 2. Вивести список для контролю
  list<int>::iterator it = l.begin();
  cout << "Old list: " << endl;
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 3. Демонстрація алгоритму replace.
  // Замінити усі числа які лежать в діапазоні [3; 7]
  // на число 0.
  replace_if(l.begin(), l.end(), Between_3_7, 0);

  // 4. Вивести новий список
  cout << "A new list:" << endl;
  it = l.begin();
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
}

Результат

Old list:
2 8 5 1 10 5 9 9 3 5
A new list:
2 8 0 1 10 0 9 9 0 0

 

3. Алгоритм replace_copy_if. Замінити символи в послідовності на основі заданого предикату або лямбда-виразу з одночасним створенням нової послідовності-копії

Алгоритм replace_copy_if робить перевірку кожного елементу у вихідному діапазоні і замінює його, якщо цей елемент відповідає заданому критерію. Критерій відповідності може бути заданий з допомогою предикату або лямбда-виразу.

Оголошення алгоритму виглядає наступним чином

template <class InputIterator, class OutputIterator, class UnaryPredicate, class Type>
OutputIterator replace_copy_if(
  InputIterator first,
  InputIterator last,
  OutputIterator result,
  UnaryPredicate pred,
  const Type& value);

тут

  • first, last – ітератори вводу, які задають вихідний діапазон;
  • result – ітератор виводу, який вказує на позицію першого елементу в діапазоні призначення. У цей діапазон відбувається копіювання елементів з вихідного діапазону;
  • pred – унарний предикат, який визначає критерій відповідності елементу з діапазону [first; last-1];
  • value – нове значення, яке присвоюється елементам.

Приклад.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
#include <time.h>
using namespace std;

void main()
{
  // Алгоритм replace_copy_if - замінює символи в послідовності
  // на основі заданого предикату.
  // Створює нову результуючу послідовність.

  // 1. Створити список
  list<int> l;

  // Заповнити список новими значеннями 1..10
  for (int i = 0; i < 10; i++)
    l.push_back(rand() % (10 - 1 + 1) + 1);

  // 2. Вивести список для контролю
  list<int>::iterator it = l.begin();
  cout << "Old list: " << endl;
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 3. Демонстрація функції replace_copy_if()
  // 3.1. Створити новий список-результат
  list<int> l2(l.size());

  // 3.2. Виклик алгоритму replace_copy_if з використанням лямбда-виразу
  replace_copy_if(
    l.begin(),
    l.end(),
    l2.begin(),
    [](int value) { return value > 5; }, // лямбда-вираз - значення що більше 5
    0
  ); // замінює усі числа що більше 5 на число 0

  // 4. Вивести новий список
  cout << "A new list:" << endl;
  it = l2.begin();
  while (it != l2.end())
  {
    cout << *it << " ";
    it++;
  }
}

Результат

Old list:
2 8 5 1 10 5 9 9 3 5
A new list:
2 0 5 1 0 5 0 0 3 5

 

4. Алгоритм replace_copy. Замінити одні символи в послідовності на інші символи зі створенням результуючої послідовності-копії

Алгоритм replace_copy перевіряє кожен елемент у вихідному діапазоні і замінює його на нове значення. Поширена реалізація алгоритму має наступне оголошення

template <class InputIterator, class OutputIterator, class Type>
OutputIterator replace_copy(
  InputIterator first,
  InputIterator last,
  OutputIterator result,
  const Type& oldVal,
  const Type& newVal);

тут

  • first, last – ітератори вводу, що задають діапазон в якому відбувається пошук елементу;
  • result – ітератор виводу, який визначає результуючий діапазон;
  • oldVal – значення елементів, які потрібно замінити;
  • newVal – значення елементів, які замінюють старі значення oldVal.

Приклад.

#include <iostream>
#include <list>
#include <algorithm>
#include <vector>
#include <functional>
#include <time.h>
using namespace std;

void main()
{
  // Алгоритм replace_copy - замінює символи в послідовності.
  // Створює нову результуючу послідовність.

  // 1. Створити список
  list<int> l;

  // Заповнити список новими значеннями 2..5
  for (int i = 0; i < 10; i++)
    l.push_back(rand() % (5 - 2 + 1) + 2);

  // 2. Вивести список для контролю
  list<int>::iterator it = l.begin();
  cout << "Old list: " << endl;
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 3. Демонстрація функції replace_copy()
  // 3.1. Створити новий список-результат
  list<int> l2(l.size());

  // 3.2. Виклик алгоритму replace_copy
  replace_copy(l.begin(), l.end(), l2.begin(), 2, 3); // замінює усі числа 2 на 3

  // 4. Вивести новий список
  cout << "A new list:" << endl;
  it = l2.begin();
  while (it != l2.end())
  {
    cout << *it << " ";
    it++;
  }
}

Результат

Old list:
3 5 4 2 3 2 4 4 4 2
A new list:
3 5 4 3 3 3 4 4 4 3

 


Споріднені теми