c++ set_union iterator

759 views Asked by At

I am having some issues with this code, the code is compiling, but when I try to test the vector's contents, the tests are failing. Here is the code:

using std::vector;

// returns a different vector, containing all elements in v1 and all elements in v2                          (elements who are either in v1 or v2) but no duplicates.

template <typename T> vector<T> set_union(const vector<T>& v1, const vector<T>&v2)
{
    vector<T> v(20);
    typename vector<T>::iterator it;

    it = set_union (v1.begin(), v1.end(), v2.begin(), v2.end(), v.begin());
    return v;
}

And here is the test I am running:

TEST_F(MyTest,set_union) {
        vector<int> v1{1,3,2};
        vector<int> v2{1,4};
        vector<int> v=set_union(v1,v2);
        ASSERT_EQ(0,count(v,9));
        ASSERT_EQ(1,count(v,1));
        ASSERT_EQ(1,count(v,2));
        ASSERT_EQ(1,count(v,3));
        ASSERT_EQ(1,count(v,4));

}

When I run these tests, the first test passes, but the second test returns 0 instances of the number 1 in the vector, where the answer should be 1 instance.

1

There are 1 answers

1
Mark B On

The problem is that std::set_union requires the input data to be sorted, which your v1 is not.

EDIT: As noted in a comment you shouldn't pre-size your vector as it will wind up with a bunch of 0s unless you have exactly 20 items in the unioned result. Instead, what about something like this (I changed the name to make it more descriptive, and ninja-edited in a call to reserve a minimum size bound based on a comment):

template <typename T>
std::vector<T> vector_union(const std::vector<T>& v1, const std::vector<T>& v2)
{
    vector<T> v;
    v.reserve(std::max(v1.size(), v2.size());

    set_union (v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(v));

    return v;
}

If desired you could even have this sort the vectors before calling set_union but that causes unneeded work for pre-sorted inputs.