Подтвердить что ты не робот

Как преобразовать вектор в набор?

У меня есть вектор, в котором я сохраняю объекты. Мне нужно преобразовать его в набор. Я читал о наборе, но у меня все еще есть пара вопросов:

Как правильно его инициализировать? Честно говоря, некоторые уроки говорят, что это нормально, чтобы инициализировать его как set<ObjectName> something. Другие говорят, что вам тоже нужен итератор, например set<Iterator, ObjectName> something.

Как правильно вставить их. Опять же, достаточно ли просто написать something.insert(object) и что все?

Как получить конкретный объект (например, объект, имеющий в нем переменную имени, равную "ben" ) из набора?

P.S. Я преобразовал вектор в себя как набор (a.k.a. Я должен использовать набор, а не вектор). В моем коде может быть только набор.

4b9b3361

Ответ 1

Вы не много рассказывали нам о своих объектах, но предположим, что у вас есть такой класс:

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

Вы хотите поместить некоторые вещи в набор, поэтому попробуйте следующее:

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

Это не удается, потому что сортировки отсортированы, и нет способа сортировать Things, потому что нет возможности сравнить два из них. Вы должны указать либо 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;

или объект функции сравнения:

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;

Чтобы найти Вещь, чье имя "ben", вы можете перебирать множество, но это действительно помогло бы, если бы вы сказали нам более конкретно, что вы хотите сделать.

Ответ 2

Предположим, что у вас есть вектор строк, чтобы преобразовать его в набор, который вы можете:

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

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

Для других типов вы должны иметь operator<.

Ответ 3

Все ответы до сих пор скопировали vector в set. Поскольку вы попросили "преобразовать" vector в set, я покажу более оптимизированный метод, который перемещает каждый элемент в set вместо копирования каждого элемента:

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

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

Примечание. Для этого вам нужна поддержка С++ 11.

Ответ 4

Вы можете инициализировать набор, используя объекты в векторе, следующим образом:

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

Это легкая часть. Теперь вам нужно понять, что для хранения элементов в наборе необходимо, чтобы оператор bool operator<(const T&a, const T& b) перегружался. Также в наборе вы можете иметь не более одного элемента с заданным значением в соответствии с определением оператора. Поэтому в наборе s у вас не может быть двух элементов, для которых ни operator<(a,b), ни operator<(b,a) не являются истинными. Пока вы знаете и понимаете, что вам должно быть хорошо идти.

Ответ 5

Если все, что вы хотите сделать, это сохранить элементы, которые у вас уже есть в векторе, в наборе:

std::vector<int> vec;
// fill the vector
std::set<int> myset(vec.begin(), vec.end());

Ответ 6

Создание набора подобно созданию вектора. Где у вас

std::vector<int> my_vec;

(или какой-либо другой тип, а не int) замените его на

std::set<int> my_set;

Чтобы добавить элементы в набор, используйте insert:

my_set.insert(3);
my_set.insert(2);
my_set.insert(1);

Ответ 7

Как правильно его инициализировать?

std::set<YourType> set;

Единственное условие состоит в том, что YourType должен иметь bool operator<(const YourType&) const и путем копирования (стандартный конструктор + оператор присваивания). Для std::vector достаточно скопировать.

Как правильно вставить их.

set.insert(my_elem);

Как получить конкретный объект (например, объект, имеющий в нем переменную имени, равную "ben" ) из набора?

Это, может быть, и дело. Набор - это всего лишь куча объекта, если вы можете просто проверить, что объект внутри, или перебрать весь набор.