elegant way to remove all elements of a vector that are contained in another vector?

后端 未结 5 776
Happy的楠姐
Happy的楠姐 2021-02-14 00:08

While looking over some code I found loopy and algorithmically slow implementation of std::set_difference :

 for(int i = 0; i < a.size(); i++)
 {
  iter = std         


        
5条回答
  •  不知归路
    2021-02-14 00:47

    Sort b so you can binary search it in order to reduce time complexity. Then use the erase-remove idiom in order to throw away all elements from a that are contained in b:

    sort( begin(b), end(b) );
    a.erase( remove_if( begin(a),end(a),
        [&](auto x){return binary_search(begin(b),end(b),x);}), end(a) );
    

    Of course, you can still sacrifice time complexity for simplicity and reduce your code by removing the sort() and replacing binary_search() by find():

    a.erase( remove_if( begin(a),end(a),
        [&](auto x){return find(begin(b),end(b),x)!=end(b);}), end(a) );
    

    This is a matter of taste. In both cases you don't need heap allocations. By the way, I'm using lambda auto parameters which are C++14. Some compilers already implement that feature such as clang. If you don't have such a compiler, but only C++11 then replace auto by the element type of the container.

    By the way, this code does not mention any types! You can write a template function so it works for all kind of types. The first variant requires random access iteration of b while the second piece of code does not require that.

提交回复
热议问题