I have a std::vector<int>, and I want to delete the n'th element. How do I do that?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
I have a std::vector<int>, and I want to delete the n'th element. How do I do that?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
To delete a single element, you could do:
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
// Deletes the second element (vec[1])
vec.erase(std::next(vec.begin()));
Or, to delete more than one element at once:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(std::next(vec.begin(), 1), std::next(vec.begin(), 3));
The erase method on std::vector is overloaded, so it's probably clearer to call
vec.erase(vec.begin() + index);
when you only want to erase a single element.
Erase an element with index :
vec.erase(vec.begin() + index);
Erase an element with value:
vec.erase(find(vec.begin(),vec.end(),value));
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;
#include <iostream>
#include <vector>
using namespace std;
void printVector(const vector<int> &v)
{
for (size_t i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
}
int main()
{
vector<int> v1, v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i);
}
// print v1
cout << "v1: " << endl;
printVector(v1);
cout << endl;
// print v2
cout << "v2: " << endl;
printVector(v2);
// Erase all odd elements
cout << "--- Erase odd elements ---" << endl;
// loop with decreasing indices
cout << "Process v2 with decreasing indices: " << endl;
for (int i = v2.size() - 1; i >= 0; i--)
{
if (v2[i] % 2 != 0)
{
cout << "# ";
v2.erase(v2.begin() + i);
}
else
{
cout << v2[i] << " ";
}
}
cout << endl;
cout << endl;
// loop with increasing indices
cout << "Process v1 with increasing indices: " << endl;
for (int i = 0; i < v1.size(); i++)
{
if (v1[i] % 2 != 0)
{
cout << "# ";
v1.erase(v1.begin() + i);
}
else
{
cout << v1[i] << " ";
}
}
return 0;
}
Output:
v1:
0 1 2 3 4 5 6 7 8 9
v2:
0 1 2 3 4 5 6 7 8 9
--- Erase odd elements ---
Process v2 with decreasing indices:
# 8 # 6 # 4 # 2 # 0
Process v1 with increasing indices:
0 # # # # #
Note that on the second version with increasing indices, even numbers are not displayed as they are skipped because of i++
Note also that processing the vector in reverse order, you CAN'T use unsigned types for indices (for (uint8_t i = v.size() -1; ... won't work). This because when i equals 0, i-- will overflow and be equal to 255 for uint8_t for example (so the loop won't stop as i will still be >= 0, and probably out of bounds of the vector).
I suggest to read this since I believe that is what are you looking for.https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
If you use for example
vec.erase(vec.begin() + 1, vec.begin() + 3);
you will erase n -th element of vector but when you erase second element, all other elements of vector will be shifted and vector sized will be -1. This can be problem if you loop through vector since vector size() is decreasing. If you have problem like this provided link suggested to use existing algorithm in standard C++ library. and "remove" or "remove_if".
Hope that this helped
if you need to erase an element inside of a for-loop, do the following:
for(int i = 0; i < vec.size(); i++){
if(condition)
vec.erase(vec.begin() + i);
}
The previous answers assume that you always have a signed index. Sadly, std::vector uses size_type for indexing, and difference_type for iterator arithmetic, so they don't work together if you have "-Wconversion" and friends enabled. This is another way to answer the question, while being able to handle both signed and unsigned:
To remove:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
v.erase(iter);
}
To take:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
auto val = *iter;
v.erase(iter);
return val;
}
here is one more way to do this if you want to delete a element by finding this with its value in vector,you just need to do this on vector.
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
it will remove your value from here. thanks
You need to use the Standard Template Library's std::vector::erase function.
// Deleting the eleventh element from vector vec
vec.erase( vec.begin() + 10 );
std::vector<T,Allocator>::erase Usage:
iterator erase (iterator position); // until C++11
iterator erase( const_iterator pos ); // since C++11 and until C++20
constexpr iterator erase( const_iterator pos ); // since C++20
Here there is a single parameter, position which is an iterator pointing to a single element to be removed from the vector.
Member types iterator and const_iterator are random access iterator types that point to elements.
erase function does the following:
It removes from the vector either a single element (position) or a range of elements ([first, last)).
It reduces the container size by the number of elements removed, which are destroyed.
Note: The iterator pos must be valid and dereferenceable. Thus the end() iterator (which is valid, but is not dereferenceable) cannot be used as a value for pos.
The return value is an iterator pointing to the new location of the element that followed the last element that was erased by the function call. This is the container end of the operation that erased the last element in the sequence.
Member type iterator is a random access iterator type that points to elements.
Here, the time complexity is linear on the number of elements erased (destructions) plus the number of elements after the last element is deleted (moving).
How about this?
void squeeze(vector<int> &v)
{
int j = 0;
for (int i = 1; i < v.size(); i++)
if (v[i] != v[j] && ++j != i)
v[j] = v[i];
v.resize(j + 1);
}
the fastest way (for programming contests by time complexity() = constant)
can erase 100M item in 1 second;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
and most readable way :
vec.erase(vec.begin() + pos);