C++. STL. Модифікуючі алгоритми. Частина 4. Алгоритми що витягують з послідовності окремі елементи або групи елементів

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


Зміст


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

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

 

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

void main()
{
  // Алгоритм remove - видалити елемент з послідовності на основі його значення.
  // 1. Створити список випадкових чисел в межах [1; 20]
  list<int> l;
  srand(time(NULL));
  for (int i = 0; i < 15; i++)
    l.push_back(rand() % (20 - 1 + 1) + 1);

  // 2. Вивести сформований список
  cout << "List of integers:\n";

  // 2.1. Оголосити ітератор
  list<int>::iterator it;

  // 2.2. Встановити ітератор на перший елемент списку
  it = l.begin();

  // 2.3. Цикл виведення списку-оригіналу
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl << endl;

  // 3. Використання алгоритму remove.
  // Видалити усі елементи, що рівні 5.
  // 3.1. Обчислити к-сть елементів, що рівні 5 - використати алгоритм count
  int value_5 = count(l.begin(), l.end(), 5);

  // 3.2. Видалити елементи, що рівні 5 - викликати алгоритм remove
  remove(l.begin(), l.end(), 5);

  // 3.3. Змінити розмір послідовності l
  l.resize(l.size() - value_5);

  // 4. Вивести нову результуючу послідовність
  cout << "A new sequence: " << endl;
  it = l.begin();
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
}

Результат

List of integers:
10 20 5 12 3 7 12 13 4 20 2 6 18 10 3

A new sequence:
10 20 12 3 7 12 13 4 20 2 6 18 10 3

 

2. Алгоритм remove_if. Видалити елементи з послідовності, що задовільняють заданій умові

 

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

// Предикат, що визначає, чи число більше 10
bool More_Than_10(int value)
{
  return value > 10;
}

void main()
{
  // Алгоритм remove_if - видалити усі елементи з послідовності
  // що відповідають заданому значенню.
  // 1. Створити список випадкових чисел в межах [1; 20]
  list<int> l;
  srand(time(NULL));
  for (int i = 0; i < 15; i++)
    l.push_back(rand() % (20 - 1 + 1) + 1);

  // 2. Вивести сформований список
  cout << "List of integers:\n";

  // 2.1. Оголосити ітератор
  list<int>::iterator it;

  // 2.2. Встановити ітератор на перший елемент списку
  it = l.begin();

  // 2.3. Цикл виведення списку-оригіналу
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl << endl;

  // 3. Використання алгоритму remove_if.
  // Видалити усі елементи, що більше 10.
  // Задається предикат More_Than_10
  // 3.1. Обчислити кількість елементів, що більше 10 - алгоритм count_if
  int count = count_if(l.begin(), l.end(), More_Than_10);

  // 3.2. Сформувати новий список - розмір списку залишається 15
  remove_if(l.begin(), l.end(), More_Than_10);

  // 3.3. Змінити розмір списку
  l.resize(l.size() - count);

  // 4. Вивести нову результуючу послідовність
  cout << "A new sequence: " << endl;
  it = l.begin();
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }

  // 5. Вивести новий розмір списку
  cout << endl << l.size() << endl;
}

Результат

List of integers:
4 3 12 14 16 12 7 13 2 18 2 18 9 12 13

A new sequence:
4 3 7 2 2 9
6

 

3. Алгоритм remove_copy. Видалення елементів з послідовності та створення нової послідовності-копії

 

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

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

  // 1. Створити список випадкових символів
  list<char> l;
  srand(time(NULL));
  for (int i = 0; i < 15; i++)
    l.push_back((int)'a' + rand() % 26);

  // 2. Вивести сформований список
  cout << "List of characters:\n";

  // 2.1. Оголосити ітератор
  list<char>::iterator it;

  // 2.2. Встановити ітератор на перший елемент списку
  it = l.begin();

  // 2.3. Цикл виведення списку-оригіналу
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl << endl;

  // 3. Використання алгоритму remove_copy().
  // Видалити усі символи 'f'
  // 3.1. Оголосити новий список такого самого розміру як список l
  list<char> l2(l.size());

  // 3.2. Викликати алгоритм remove_copy
  remove_copy(l.begin(), l.end(), l2.begin(), 'f');

  // 3.3. Вивести нову результуючу послідовність
  cout << "A new sequence: " << endl;
  it = l2.begin();
  for (int i = 0; i < l2.size(); i++)
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}

Результат

List of characters:
l o s f q q h f q t u m j y j

A new sequence:
l o s q q h q t u m j y j

 

4. Алгоритм remove_copy_if. Видалити елементи з послідовності на основі заданої умови з одночасним створенням послідовності-копії

 

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

// Предикат, який визначає, чи значення менше 5
bool LessThan_5(int value)
{
  return value < 5;
}

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

  // 1. Створити список випадкових чисел в межах [1; 20]
  list<int> l;
  srand(time(NULL));
  for (int i = 0; i < 15; i++)
    l.push_back(rand() % (20 - 1 + 1) + 1);

  // 2. Вивести сформований список
  cout << "List of integers:\n";

  // 2.1. Оголосити ітератор
  list<int>::iterator it;

  // 2.2. Встановити ітератор на перший елемент списку
  it = l.begin();

  // 2.3. Цикл виведення списку-оригіналу
  while (it != l.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl << endl;

  // 3. Використання алгоритму remove_copy_if().
  // Видалити усі елементи, що менше 5
  // 3.1. Оголосити новий список такого самого розміру як список l
  list<int> l2(l.size());

  // 3.2. Викликати алгоритм remove_copy_if - сформувати список елементів,
  // які мають значення більше 5. Для цього використовується
  // предикат MoreThan_5
  remove_copy_if(l.begin(), l.end(), l2.begin(), LessThan_5);

  // 3.3. Вивести нову результуючу послідовність
  cout << "A new sequence: " << endl;
  it = l2.begin();
  for (int i = 0; i < l2.size(); i++)
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 4. Використання алгоритму remove_copy_if() у поєднанні з лямбда-виразом.
  // 4.1. Оголосити новий список такого самого розміру як список l.
  list<int> l3(l.size());

  // 4.2. Викликати алгоритм з лямбда-виразом
  remove_copy_if(l.begin(), l.end(), l3.begin(), [](int value) { return value < 5; });

  // 4.3. Вивести результат
  cout << "A new sequence: " << endl;
  it = l3.begin();
  while (it != l3.end())
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;
}

Результат

List of integers:
5 11 1 6 19 3 20 8 18 11 3 2 14 19 2

A new sequence:
5 11 6 19 20 8 18 11 14 19 0 0 0 0 0
A new sequence:
5 11 6 19 20 8 18 11 14 19 0 0 0 0 0

Як видно з результату даний алгоритм не змінює розміру результуючої послідовності. Розмір можна задати через використання алгоритму count_if та методу resize() контейнера list<T> (дивіться як це зроблено в алгоритмах remove та remove_if).

 

5. Алгоритм unique. Витягнути дублікати з послідовності

 

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

// Предикат, що визначає рівність елементів
bool Equal_Items(int a, int b)
{
  // наступний елемент більший за попередній на 1
  return a + 1 == b;
}

int main()
{
  // Алгоритм unique - витягнути дублікати з послідовності
  // { ... 3, 3, 3, ... } => { ... 3 ... }

  // 1. Використання unique без предикату
  // 1.1 Створити послідовність чисел та вивести її на консоль
  list<int> L1 = { 2, 8, 2, 2, 3, 4, 5, 8, 1 };
  cout << "L1 => ";
  for (int i : L1)
    cout << i << " ";
  cout << endl;

  // 1.2. Оголосити ітератор, який буде вказувати на кінець нової послідовності
  list<int>::iterator endL1;

  // 1.3. Створити іншу послідовніть, яка не містить дублікатів
  endL1 = unique(L1.begin(), L1.end());

  // 1.4. Вивести результуючу послідовність L1 до ітератора endL1
  cout << "L1+ => ";
  list<int>::iterator it = L1.begin();
  while (it != endL1)
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 2. Використання алгоритму з предикатом
  // 2.1. Створити послідовність чисел та вивести її на консоль
  list<int> L2 = { 2, 8, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 8, 5 };
  cout << "L2 => ";
  for (int i : L2)
    cout << i << " ";
  cout << endl;

  // 2.2. Оголосити ітератор, який буде вказувати на кінець нової послідовності
  list<int>::iterator endL2;

  // 2.3. Викликати алгоритм unique
  endL2 = unique(L2.begin(), L2.end(), Equal_Items);

  // 2.4. Вивести послідовність L2 до ітератора endL2
  cout << "L2+ => ";
  list<int>::iterator it2 = L2.begin();
  while (it2 != endL2)
  {
    cout << *it2 << " ";
    it2++;
  }
  cout << endl;
}

Результат

L1 => 2 8 2 2 3 4 5 8 1
L1+ => 2 8 2 3 4 5 8 1
L2 => 2 8 2 2 2 3 3 4 4 4 5 5 5 5 8 5
L2+ => 2 8 2 2 2 4 4 4 8 5

 

6. Алгоритм unique_copy. Витягнути дублікати з послідовності з отриманням нової послідовності

 

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

// Предикат, що визначає рівність елементів
bool Equal_Items(int a, int b)
{
  // наступний елемент більший за попередній на 1
  return a + 1 == b;
}

int main()
{
  // Алгоритм unique_copy - витягнути дублікати з послідовності
  // з отриманням нової послідовності-копії
  // { ... 3, 3, 3, ... } => { ... 3 ... }

  // 1. Використання unique_copy без предикату
  // 1.1 Створити послідовність чисел та вивести її на консоль
  list<int> L1 = { 2, 8, 2, 2, 2, 3, 3, 4, 5, 8, 1 };
  cout << "L1 => ";
  for (int i : L1)
    cout << i << " ";
  cout << endl;

  // 1.2. Створити послідовність, в яку буде записуватись результат
  list<int> L2(L1.size());

  // 1.3. Оголосити ітератор, який буде вказувати на кінець нової послідовності
  list<int>::iterator endL2;

  // 1.4. Створити іншу послідовніть, яка не містить дублікатів
  endL2 = unique_copy(L1.begin(), L1.end(), L2.begin());

  // 1.5. Вивести результуючу послідовність L2 до ітератора endL2
  cout << "L2 => ";
  list<int>::iterator it = L2.begin();
  while (it != endL2)
  {
    cout << *it << " ";
    it++;
  }
  cout << endl;

  // 2. Використання алгоритму з лямбда-виразом
  // 2.1. Створити послідовність чисел та вивести її на консоль
  list<int> L3 = { 2, 8, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 8, 5 };
  cout << "L3 => ";
  for (int i : L3)
    cout << i << " ";
  cout << endl;

  // 2.2. Створити послідовність, в яку буде записуватись результат
  list<int> L4(L3.size());

  // 2.3. Оголосити ітератор, який буде вказувати на кінець нової послідовності
  list<int>::iterator endL4;

  // 2.4. Викликати алгоритм unique_copy на основі лямбда-виразу
  // Лямбда-вираз задає правило:
  // якщо попередній елемент більше наступного, то об'єднати ці 2 елементи,
  // залишається попередній елемент.
  endL4 = unique_copy(
    L3.begin(), // початок вихідної послідовності
    L3.end(), // кінець вихідної послідовності
    L4.begin(), // початок результуючої послідовності
    [](int a, int b) { return a > b; } // тут може бути також відповідний предикат
  );

  // 2.5. Вивести послідовність L2 до ітератора endL2
  cout << "L2+ => ";
  list<int>::iterator it2 = L4.begin();
  while (it2 != endL4)
  {
    cout << *it2 << " ";
    it2++;
  }
  cout << endl;
}

Результат

L1 => 2 8 2 2 2 3 3 4 5 8 1
L2 => 2 8 2 3 4 5 8 1
L3 => 2 8 2 2 2 3 3 4 4 4 5 5 5 5 8 5
L2+ => 2 8 8

 


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