Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove the common entities from two vector?

Tags:

c++

vector

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

like image 724
yesraaj Avatar asked Mar 13 '09 07:03

yesraaj


People also ask

How do I remove multiple elements from a vector file?

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.

How do you remove a vector from a 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.

How do you find the common element of multiple vectors?

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.


1 Answers

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.

like image 96
Luc Touraille Avatar answered Oct 14 '22 18:10

Luc Touraille