Как преобразовать вектор в набор?
У меня есть вектор, в котором я сохраняю объекты. Мне нужно преобразовать его в набор. Я читал о наборе, но у меня все еще есть пара вопросов:
Как правильно его инициализировать? Честно говоря, некоторые уроки говорят, что это нормально, чтобы инициализировать его как set<ObjectName> something
. Другие говорят, что вам тоже нужен итератор, например set<Iterator, ObjectName> something
.
Как правильно вставить их. Опять же, достаточно ли просто написать something.insert(object)
и что все?
Как получить конкретный объект (например, объект, имеющий в нем переменную имени, равную "ben" ) из набора?
P.S. Я преобразовал вектор в себя как набор (a.k.a. Я должен использовать набор, а не вектор). В моем коде может быть только набор.
Ответы
Ответ 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" ) из набора?
Это, может быть, и дело. Набор - это всего лишь куча объекта, если вы можете просто проверить, что объект внутри, или перебрать весь набор.