2013-11-18 3 views
24

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

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

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

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

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

+14

'set s (v.begin(), v.end());' это простой способ. –

+1

@larsmans Нет. Мне нужно полностью преобразовать вектор в набор. Я не могу иметь их обоих в своем коде. – Marius

+0

@sharth Нет. Я могу использовать только набор. Я пытаюсь сказать, как правильно использовать set? – Marius

ответ

5

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

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

Вы хотите поместить некоторые вещи в комплекте, так что вы пытаетесь это:

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

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

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

+1

слишком длинный и неясный – sdd

76

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

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

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

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

5

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

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

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

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) не верны. Пока вы знаете и понимаете, что вам должно быть хорошо идти.

28

Все ответы до сих пор скопировали 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())); 

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

1

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

std::vector<int> my_vec; 

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

std::set<int> my_set; 

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

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

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

std::set<YourType> set; 

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

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

set.insert(my_elem); 

Как получить конкретный объект (например, объект, который имеет имя переменной в нем, которое равно «Бен») из множества?

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

+0

Ну, скажем, мы хотим найти только объект с определенным именем. Как это сделать? – Marius

+0

Вам придется перебирать весь набор, например: 'std :: find_if (set.begin(), set.end(), [] (const YourType & type) {return type.name ==" value " }); ' – Johan

+0

В этом случае, если это единственный (или почти единственный) способ поиска элемента,' std :: map 'должен быть намного более эффективным. – Johan

Смежные вопросы