Рассмотрим только элементы, находящиеся в рамках диапазона от итератора begin
new_end
. Элемент, на который указывает итератор new_end
, является 1
до 8
включительно), мы понимаем, что перед нами корректный диапазон, из которого удалены все значения 2
.Здесь вступает в дело функция erase
new_end
и end
больше к нему не относятся. Вектор легко с этим справится, поскольку может просто перевести конечный итератор в позицию, обозначенную new_end
. Обратите внимание: итератор new_end
является возвращаемым значением вызова std::remove
, следовательно, можно просто им воспользоваться.
В конечном счете вектор выглядит так, как показано в шаге 3: считается, что его размер
Чтобы вектор занимал ровно столько памяти, сколько ему нужно, в конце работы мы вызываем метод shrink_to_fit
В шаге 8 мы определили функцию-
std::remove_if
. Это работает, поскольку независимо от того, какой итератор вернет функция, его можно будет безопасно применить в функции вектора erase
. Если мы std::remove_if
не выполнит никаких действий и вернет конечный итератор. Далее вызов наподобие v.erase(end, end);
также ни к чему не приведет.Дополнительная информация
Функция std::remove
std::array
обратите внимание, что массив не поддерживает вызов функции erase из второго шага, поскольку вы не можете изменять его размер автоматически. Несмотря на то что функция std::remove
, по сути, лишь перемещает элементы и не удаляет их, она пригодна для структур данных наподобие массивов, которые не могут изменять размер. При работе с массивом можно переписать значения после конечного итератора некоторыми граничными значениями, например '\0'
для строк.Удаляем элементы из неотсортированного объекта класса std::vector за время O(1)
Удаление элементов из середины вектора занимает
Такое перемещение с сохранением порядка может оказаться затратным по времени, если перемещаемые элементы сложны и/или велики и содержат много объектов. Если порядок сохранять не требуется, можно оптимизировать процесс, как показано в этом разделе.
Как это делается
В этом примере мы заполним экземпляр класса std::vector
1. Сначала включим необходимые заголовочные файлы:
#include
#include
#include
2. Далее определим функцию main
int main()
{
std::vector
3. Очередной шаг заключается в том, чтобы удалить значение с индексом 2
789
). Функция, которую мы будем использовать для данной задачи, еще не реализована. Мы сделаем это спустя несколько шагов. Затем выведем содержимое вектора: quick_remove_at(v, 2);
for (int i : v) {
std::cout << i << ", ";
}
std::cout << '\n';
4. Теперь удалим еще один элемент. Это будет значение 123
std::find
, которая принимает диапазон (наш вектор) и значение, а затем ищет позицию значения. После этого она возвращает 123
. Мы используем его для той же функции quick_remove_at
, но на сей раз применим
qu
for (int i : v) {
std::cout << i << ", ";
}