Шаг 106.
Библиотека STL.
Модифицирующие алгоритмы. "Удаление" элементов

    На этом шаге мы рассмотрим алгоритм, используемый для удаления элементов.

    Алгоритм remove() удаляет элементы из заданного интервала. Но если вызвать его для всех элементов контейнера, происходит нечто неожиданное. Пример:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream>
#include <iterator>
#include <list>
#include <string>
#include <algorithm>
#include <conio.h> //необходимо для getch()
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
using namespace std;
std::string ToRus(const std::string &in)
{
  char *buff = new char [in.length()+1];
  CharToOem(in.c_str(),buff);
  std::string out(buff);
  delete [] buff;
  return out;
}

int main(int argc, char* argv[])
{
  list<int> coll;
  // Вставка элементов со значениями от 6 до 1 и от 1 до 6
  for (int i=1; i<=6; ++i) {
    coll.push_front(i);
    coll.push_back(i);
  }
  // Вывод всех элементов коллекции
  cout << ToRus("Список чисел:\n");
  copy (coll.begin(), coll.end(), // Источник
    ostream_iterator<int>(cout," ")); // Приемник

  cout << endl;

  // Удаление всех элементов со значением 3
  remove (coll.begin(), coll.end(),   // Интервал
    3);  // Значение

    // Вывод всех элементов коллекции
  cout << ToRus("Список чисел:\n");
  copy (coll.begin(), coll.end(), // Источник
    ostream_iterator<int>(cout," ")); // Приемник

  cout << endl;

  getch();
  return 0;
}
//---------------------------------------------------------------------------
Текст этого примера можно взять здесь.

    При поверхностном знакомстве с предметом напрашивается предположение, что эта программа удаляет из коллекции все элементы со значением 3. Но на самом деле результат выглядит так:


Рис.1. Результат работы приложения

    Алгоритм remove() не изменил количество элементов в коллекции, для которой он вызывался. Функция end() возвращает прежнее значение, а функция size() - прежнее количество элементов. Тем не менее кое-что все же изменилось: порядок следования элементов стал таким, каким он должен стать после удаления. На место элементов со значением 3 были записаны следующие элементы (рисунок 2).


Рис.2. Принцип действия алгоритма remove()

    Прежние элементы в конце коллекции, не перезаписанные алгоритмом, остались без изменений. На логическом уровне эти элементы уже не принадлежат коллекции.

    На следующем шаге мы рассмотрим закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг