Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between remove-erase and find-erase

Tags:

c++

stl

Suppose you want to remove a single element from a vector by value. What is the difference between remove-erase:

vector<int> v;
// add some values
vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it);

And find-erase

vector<int> v;
// add some values
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if(it != v.end())
{
  v.erase(it);
}
like image 736
oggmonster Avatar asked Nov 15 '13 11:11

oggmonster


People also ask

What is the difference between remove and delete?

What's the difference between delete and remove? This is a simple definition: Remove and Delete are defined quite similarly, but the main difference between them is that delete means erase (i.e. rendered nonexistent or unrecoverable), while remove denotes take away and set aside (but kept in existence).

What is the difference between remove and erase in C++?

Therefore, erase() is something you can do to an element in a container, remove() is something you can do to a range as it re-arranges that range but doesn't erase anything from the range..

Does erase mean delete?

When you erase something, you eliminate or delete it, often by physically wiping it out. It's easy to erase chalk from a blackboard, but not so easy to erase graffiti from the side of a building.

What is computer erase?

Erase is a term that describe the process of removing or deleting data. In most situations, when data is deleted or erased from the hard drive, it's marked as deleted yet remains on the hard drive until it's overwritten by something else.


1 Answers

Your remove-erase code is not correct. The remove-erase idiom looks like this:

vector<int>::iterator it = remove(v.begin(), v.end(), 5);
v.erase(it, v.end());

In that case, it has the effect of erasing all values equal to 5 but it minimises the amount of copying required to achieve that.

Your find-erase code removes only the first value equal to 5, so it does what you want.

Your remove-erase code moves all the values not equal to 5 to the front of the vector (that's what std::remove does), erases one of the remaining elements of the vector, and leaves any remaining elements after that with unspecified values (which is also what remove does). It has undefined behavior if the vector doesn't contain a 5 to begin with, because remove would return v.end() in that case.

So, if you only want to erase a single element of several equal to 5 then std::remove is no use to you because it doesn't preserve the (other) 5s. If you want to move the non-5 values to the start and the 5 values to the end, before removing the first of the 5s, then you could in fact do that with std::partition just not with std::remove:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.erase(it);

Although, since one 5 is as good as another you get the same result by erasing the last of the 5s rather than the first, and it's more efficient when there's more than one of them:

auto it = partition(v.begin(), v.end(), [](int i) { return i != 5; });
if (it != v.end()) v.pop_back();

If you can somehow be sure that the vector initially contains exactly one element equal to 5 (no more or less), then your two bits of code do the same thing. And in that case you wouldn't need the test for it != v.end() in the find-erase code, you would know it isn't equal. You could just do v.erase(find(v.begin(), v.end(), 5)).

like image 99
Steve Jessop Avatar answered Sep 28 '22 08:09

Steve Jessop