54

I have a vector, in which I save objects. I need to convert it to set. I have been reading about set, 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 specific object (for example object, which has name variable in it, which is equal to "ben") from set?

P.S. I have convert vector it self to be as a set (a.k.a. I have to use set rather then vector). Only set can be in my code.

Marius
  • 651
  • 1
  • 5
  • 8

7 Answers7

158

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
  • 51,434
  • 14
  • 119
  • 190
56

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,512
  • 14
  • 28
David
  • 25,830
  • 16
  • 80
  • 130
14

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
  • 64,309
  • 15
  • 111
  • 164
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,149
  • 1
  • 23
  • 37
3

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
  • 86,746
  • 10
  • 132
  • 141
1

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,603
  • 12
  • 24
  • 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
  • 69,019
  • 6
  • 64
  • 147