Как удалить элемент из std:: vector по индексу?
У меня есть std::vector, и я хочу удалить n-й элемент. Как мне это сделать?
10 ответов
чтобы удалить один элемент, вы можете сделать:
или, чтобы удалить более одного элемента за один раз:
метод erase на std:: vector перегружен, поэтому, вероятно, яснее вызвать
когда вы хотите стереть только один элемент.
на erase метод будет использоваться двумя способами:
удаление одного элемента:
удаление ряда элементов:
на самом деле erase функция работает для двух профилей:
удаление одного элемента
удаление ряда элементов
С std:: vec.begin () отмечает начало контейнера, и если мы хотим удалить I-й элемент в нашем векторе, мы можем использовать:
если присмотреться, ВЭК.begin () — это просто указатель на начальную позицию нашего вектора и добавление значение i к нему увеличивает указатель на позицию i, поэтому вместо этого мы можем получить доступ к указателю на I-й элемент по:
Итак, мы можем написать:
Если у вас есть неупорядоченный вектор, вы можете воспользоваться тем, что он неупорядочен, и использовать то, что я видел от Дэна Хиггинса в CPPCON
поскольку порядок списка не имеет значения, просто возьмите последний элемент в списке и скопируйте его поверх элемента, который вы хотите удалить, затем поп и удалить последний элемент.
Если вы работаете с большими векторами (размер > 100,000) и хотите удалить много элементов, я бы рекомендовал сделать что-то вроде этого:
код принимает каждое число в vec, которое не может быть разделено на 3, и копирует его в vec2. Впоследствии он копирует vec2 в vec. Это довольно быстро. Для обработки 20,000,000 элементов этот алгоритм занимает всего 0,8 сек!
Я сделал то же самое с методом стирания, и это занимает много и много времени:
чтобы удалить элемент, используйте следующий способ:
предыдущие ответы предполагают, что вы всегда подписанный индекс. К сожалению, std::vector использует size_type для индексации, и difference_type для арифметики итератора, поэтому они не работают вместе, если у вас есть» — Wconversion » и друзья включены. Это еще один способ ответить на вопрос, имея возможность обрабатывать как подписанные, так и неподписанные:
вот еще один способ сделать это,если вы хотите удалить элемент, найдя это со значением в векторе, вам просто нужно сделать это на векторе.
Операции с векторами в STL
Размер вектора можно узнать при помощи универсального метода size() , возвращающего для всех контейнеров в STL их размер. Также есть метод empty() , возвращающий логическое значение ( true , если вектор пустой).
Размер вектора можно изменить в любой момент, при помощи метода resize . У этого метода может быть один или два параметра. Вызов метода resize(n) изменяет размер вектора до n элементов (длина вектора может как уменьшится, так и увеличиться). Вызов метода resize(n, val) изменяет размер вектора до n элементов, и если при этом размер вектора увеличивается, то новые элементы получают значение, равное val.
Очень часто бывает полезно добавлять элементы в конец вектора по одному и удалять элементы из конца вектора по одному. Для добавления нового элемента, равного val в конец вектора используется метод push_back(val) . Для удаления последнего элемента вектора используется метод pop_back() — он не возвращает значения.
Добавление элемента в конец вектора осуществляется в среднем за O(1). Это реализовано за счет того, что память для хранения элементов вектора выделяется “с запасом”, то есть можно будет добавлять элементы по одному, пока не кончится запас памяти. Если запас памяти исчерпан, выделяется новая память, при этом «запас» размера вектора удваивается.
Очистить вектор можно при помощи метода clear() .
Вставка и удаление элементов в середину вектора
Для удаления и вставки элементов в середину вектора используются методы erase и insert . В качестве параметра им нужно передавать итератор, поэтому просто покажем на примере, как их использовать.
Итератор — специальный объект, указывающий на элемент вектора (или другой структуры данных). Итератор на элемент с индексом i можно получить при помощи выражения a.begin() + i . Кроме того, можно при помощи итератора a.end() “отсчитывать” элементы, начиная с конца. При этом a.end() будет итератором на элемент, следующий за последним, a.end() будет итератором на последний элемент, то есть то же самое, что a.begin() + a.size() — 1 , a.end() — 2 — второй элемент с конца и т.д.
Удаление элементов: метод erase
Метод erase позволяет удалять из середины вектора один или несколько элементов. Если вызвать метод erase с одним параметром–итератором, то будет удален соответствующий элемент из вектора, то есть для удаления элемента с индексом i из вектора a нужно вызвать метод следующим образом:
Методу erase передать два итератора на начало и конец удаляемого фрагмента, например:
В этом случае будут удалены элементы с индексами от i (включительно) до j не включительно, то есть элементы a[i] , a[i + 1] , . a[j — 1] . Всего будет удалено j — i элементов.
Методу erase можно передавать и итераторы, полученные относительно итератора end . Например, удалить из вектора три последних элемента можно так:
Подробней про его использование можно прочитать в документации.
Вставка элементов: метод insert
Метод insert позволяет вставлять в середину вектора новый элемент, или несколько равных элементов, или другой вектор, или фрагмент другого вектора. Этот метод также работает с итераторами и про его использование можно прочитать в документации.
Примеры использования метода insert :
Вставка одного элемента со значением val в позицию с индексом i :
Вставка нескольких равных (количеством count ) элементов со значением val в позицию с индексом i :
Вставка в вектор a в позицию с индексом i фрагмент вектора b с индексами от start включительно до finish не включительно:
В качестве параметром могут использоваться произвольные итераторы. Рассмотрим несколько примеров:
Весь вектор b добавить в конец вектора a :
Последние 5 элементов вектора b вставить в начало вектора a :
Поскольку вставка и удаление элементов требуют сдвига других элементов вектора, эти операции имеют линейную сложность, то есть выполняются за время, пропорциональное длине вектора.
Присваивание и сравнение векторов
Содержимое одного вектора можно целиком скопировать в другой вектор при помощи операции присваивания. При этом размер вектора A автоматически изменится и будет равен размеру вектора B . A = B .
Также векторы можно сравнивать на равенство и неравенство ( A == B , A != B ), и сравнивать их содержимое в лексикографическом порядке ( A < B , A <= B , A > B , A >= B ).
How do I erase an element from std::vector<> by index?
I have a std::vector<int>, and I want to delete the n’th element. How do I do that?
![]()
16 Answers 16
To delete a single element, you could do:
Or, to delete more than one element at once:
The erase method on std::vector is overloaded, so it’s probably clearer to call
when you only want to erase a single element.
![]()
The erase method will be used in two ways:
Erasing single element:
Erasing range of elements:
Erase an element with index :
Erase an element with value:
Actually, the erase function works for two profiles:
Removing a single element
Removing a range of elements
Since std::vec.begin() marks the start of container and if we want to delete the ith element in our vector, we can use:
If you look closely, vec.begin() is just a pointer to the starting position of our vector and adding the value of i to it increments the pointer to i position, so instead we can access the pointer to the ith element by:
So we can write:
![]()
![]()
If you have an unordered vector you can take advantage of the fact that it’s unordered and use something I saw from Dan Higgins at CPPCON
Since the list order doesn’t matter, just take the last element in the list and copy it over the top of the item you want to remove, then pop and delete the last item.
![]()
It may seem obvious to some people, but to elaborate on the above answers:
If you are doing removal of std::vector elements using erase in a loop over the whole vector, you should process your vector in reverse order, that is to say using
for (int i = v.size() — 1; i >= 0; i—)
instead of (the classical)
for (int i = 0; i < v.size(); i++)
The reason is that indices are affected by erase so if you remove the 4-th element, then the former 5-th element is now the new 4-th element, and it won’t be processed by your loop if you’re doing i++ .
Below is a simple example illustrating this where I want to remove all the odds element of an int vector;
Note that on the second version with increasing indices, even numbers are not displayed as they are skipped because of i++