Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union Operation For std::set [duplicate]

Tags:

c++

Is there no function in the standard library like this?

set<T> set::union(set<T> other)

Or even this?

set<T> getUnion(set<T> a, set<T> b)

set_union is the right function in name only. It can operate on vector also, which means it may not be as efficient as a set-only function.

I am not appending. Appending destroys the original set. I want a new set representing the union.

like image 513
Chris Redford Avatar asked May 02 '14 21:05

Chris Redford


People also ask

How do you take the union of two sets in C++?

C++ Algorithm set_union() C++ Algorithm set_union() function is used to find the union of two sorted ranges [first1, last1) and [first2, last2), which is formed by the elements that are present in either one of the sets or in both.

How do you perform a union operation in C++?

The union of two sets is formed by the elements that are present in either one of the sets, or in both. Elements from the second range that have an equivalent element in the first range are not copied to the resulting range. The elements are compared using operator< for the first version, and comp for the second.

How do you add one set to another?

The set::insert is a built-in function in C++ STL which insert elements in the set container or inserts the elements from a position to another position in the set to a different set. Parameters: The function accepts a mandatory parameter element which is to be inserted in the set container.

What is union in C++ with example?

In C++17 and later, the std::variant class is a type-safe alternative for a union. A union is a user-defined type in which all members share the same memory location. This definition means that at any given time, a union can contain no more than one object from its list of members.


2 Answers

You can use the two-iterator std::set::insert template for this:

template <typename T>
std::set<T> getUnion(const std::set<T>& a, const std::set<T>& b)
{
  std::set<T> result = a;
  result.insert(b.begin(), b.end());
  return result;
}

Note: Following some of the comments suggesting I take one of the parameters by value because I need a copy anyway, I chose this implementation to avoid disallowing RVO, which is not allowed when returning parameter taken by value. To better deal with rvalue arguments, overloads of this function taking rvalue reverences and leveraging move semantics could be provided.

like image 120
juanchopanza Avatar answered Sep 17 '22 14:09

juanchopanza


There's std::set_union.

The example from that page uses vectors and arrays, so it's pretty versatile:

// set_union example
#include <iostream>     // std::cout
#include <algorithm>    // std::set_union, std::sort
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
  std::vector<int>::iterator it;

  std::sort (first,first+5);     //  5 10 15 20 25
  std::sort (second,second+5);   // 10 20 30 40 50

  it=std::set_union (first, first+5, second, second+5, v.begin());
                                               // 5 10 15 20 25 30 40 50  0  0
  v.resize(it-v.begin());                      // 5 10 15 20 25 30 40 50

  std::cout << "The union has " << (v.size()) << " elements:\n";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

Output:

The union has 8 elements:
 5 10 15 20 25 30 40 50
like image 36
keyser Avatar answered Sep 19 '22 14:09

keyser