say I have vector<class1a>,vector<class1b>
how to remove the common entities from both of them
I have defined ==operator for the class1 objects class1a,class1b
If you need to remove multiple elements from the vector, the std::remove will copy each, not removed element only once to its final location, while the vector::erase approach would move all of the elements from the position to the end multiple times. For Example, Consider removing all elements < 5 in following vector.
All the elements of the vector are removed using clear() function. erase() function, on the other hand, is used to remove specific elements from the container or a range of elements from the container, thus reducing its size by the number of elements removed.
1 Answer. To find the common elements from multiple vectors, you can use the intersect function from the sets base R package. vectors (of the same mode) containing a sequence of items (conceptually) with no duplicate values. Intersect will discard any duplicated values in the arguments, and they apply as.
The stl algorithms provide several functions to perform set operations, notably calculating the set symmetric difference, which is what you need.
Here's an example of use:
#include <algorithm>
#include <vector>
int main(int argc, char **argv) {
std::vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
std::vector<int> v2;
v2.push_back(2);
v2.push_back(4);
v2.push_back(6);
v2.push_back(8);
// Ranges must be sorted!
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
std::vector<int> res; // Will contain the symmetric difference
std::set_symmetric_difference(v1.begin(), v1.end(),
v2.begin(), v2.end(),
std::back_inserter(res));
// Copy result to the output
std::copy(res.begin(), res.end(), std::ostream_iterator<int>(cout, " "));
// Prints "1 3 5"
return 0;
}
std::set_symmetric_difference
takes two range (i.e. two pairs of OutputIterators) and an InputIterator where it will put the result. It also returns an iterator to the end of the result range.
EDIT
I just read your comments on your question. If you want the two original vectors to be modified, you can use std::set_difference
:
vector<int>::iterator endRange;
endRange = set_difference(v1.begin(), v1.end(),
v2.begin(), v2.end(),
v1.begin());
v1.erase(endRange, v1.end());
Here, we put the result of the set difference v1 - v2 into v1. However, we can't do the vice-versa since v1 is now modified. The solution is to calculate the intersection of v1 and v2, and then the difference with this intersection std::set_intersection
:
vector<int> inter;
set_intersection(v1.begin(), v1.end(),
v2.begin(), v2.end(),
back_inserter(inter));
// inter is "2 4 6"
v1.erase(set_difference(v1.begin(), v1.end(),
inter.begin(), inter.end(),
v1.begin()),
v1.end());
// v1 is "1 3 5"
v2.erase(set_difference(v2.begin(), v2.end(),
inter.begin(), inter.end(),
v2.begin()),
v2.end());
// v2 is "8"
I guess there are much more performant solutions, but this one is clear, and really convey your intents by using widely known stl algorithms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With