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

 


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