90

I have a vector, in which I save objects. I need to convert it to set. I have been reading about sets, but I still have a couple of questions:

  • How to correctly initialize it? Honestly, some tutorials say it is fine to initialize it like set<ObjectName> something. Others say that you need an iterator there too, like set<Iterator, ObjectName> something.

  • How to insert them correctly. Again, is it enough to just write something.insert(object) and that's all?

  • How to get a specific object (for example, an object which has a named variable in it, which is equal to "ben") from the set?

I have to convert the vector itself to be a set (a.k.a. I have to use a set rather than a vector).

Marius
  • 1,011
  • 1
  • 7
  • 9

7 Answers7

199

Suppose you have a vector of strings, to convert it to a set you can:

std::vector<std::string> v;

std::set<std::string> s(v.begin(), v.end());

For other types, you must have operator< defined.

masoud
  • 55,379
  • 16
  • 141
  • 208
79

All of the answers so far have copied a vector to a set. Since you asked to 'convert' a vector to a set, I'll show a more optimized method which moves each element into a set instead of copying each element:

std::vector<T> v = /*...*/;

std::set<T> s(std::make_move_iterator(v.begin()),
              std::make_move_iterator(v.end()));

Note, you need C++11 support for this.

Bula
  • 1,590
  • 1
  • 14
  • 33
David
  • 27,652
  • 18
  • 89
  • 138
17

You can initialize a set using the objects in a vector in the following manner:

vector<T> a;
... some stuff ...
set<T> s(a.begin(), a.end());

This is the easy part. Now, you have to realize that in order to have elements stored in a set, you need to have bool operator<(const T&a, const T& b) operator overloaded. Also in a set you can have no more then one element with a given value acording to the operator definition. So in the set s you can not have two elements for which neither operator<(a,b) nor operator<(b,a) is true. As long as you know and realize that you should be good to go.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
7

If all you want to do is store the elements you already have in a vector, in a set:

std::vector<int> vec;
// fill the vector
std::set<int> myset(vec.begin(), vec.end());
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
5

You haven't told us much about your objects, but suppose you have a class like this:

class Thing
{
public:
  int n;
  double x;
  string name;
};

You want to put some Things into a set, so you try this:

Thing A;
set<Thing> S;
S.insert(A);

This fails, because sets are sorted, and there's no way to sort Things, because there's no way to compare two of them. You must provide either an operator<:

class Thing
{
public:
  int n;
  double x;
  string name;

  bool operator<(const Thing &Other) const;
};

bool Thing::operator<(const Thing &Other) const
{
  return(Other.n<n);
}

...
set<Thing> S;

or a comparison function object:

class Thing
{
public:
  int n;
  double x;
  string name;
};

struct ltThing
{
  bool operator()(const Thing &T1, const Thing &T2) const
  {
    return(T1.x < T2.x);
  }
};

...
set<Thing, ltThing> S;

To find the Thing whose name is "ben", you can iterate over the set, but it would really help if you told us more specifically what you want to do.

Beta
  • 96,650
  • 16
  • 149
  • 150
2

How to correctly initialize it?

std::set<YourType> set;

The only condition is that YourType must have bool operator<(const YourType&) const and by copyable (default constructor + assignment operator). For std::vector copyable is enough.

How to insert them correctly.

set.insert(my_elem);

How to get specific object (for example object, which has name variable in it, which is equal to "ben") from set?

That's maybe the point. A set is just a bunch of object, if you can just check that an object is inside or iterate throught the whole set.

Johan
  • 3,728
  • 16
  • 25
  • Well lets say we want to only find an object with specific name in it. How to do it? – Marius Nov 18 '13 at 16:47
  • You'll have to iterate through the whole set, something like: `std::find_if(set.begin(), set.end(), [](const YourType& type) { return type.name == "value" });` – Johan Nov 18 '13 at 16:48
  • In that case, if this is the only (or almost only) way to search for an element, a `std::map` should be a lot more efficient. – Johan Nov 18 '13 at 16:50
0

Creating a set is just like creating a vector. Where you have

std::vector<int> my_vec;

(or some other type rather than int) replace it with

std::set<int> my_set;

To add elements to the set, use insert:

my_set.insert(3);
my_set.insert(2);
my_set.insert(1);
Pete Becker
  • 74,985
  • 8
  • 76
  • 165