2013-04-29 2 views
33

Это может быть глупый вопрос, я совершенно новичок в C++ и программировании в целом. Я хочу понять использование нескольких контейнеров STL и с учетом этого, мне было интересно, какие преимущества имеют использование std :: set vs, например, с использованием векторов или карт? Я не могу найти явного ответа на этот вопрос. Я заметил, что наборы используют карты, но почему бы не всегда использовать карты или всегда использовать наборы. Вместо этого предоставляются 2 довольно похожих контейнера. Спасибо заранее.Преимущества std :: set vs vectors или maps

+1

«std :: set» похож на «std :: map» без значения и полностью не связан с 'std :: vector' ... –

+0

Вам нужна [хорошая документация] (http: // en.cppreference.com/w/). –

+6

Все они делают разные вещи. Выберите тот, который вам нужен, чтобы решить вашу проблему.Это похоже на вопрос, почему мы должны хранить соль, масло и сахар на кухне, а не всегда использовать апельсиновый сок. –

ответ

55

И std::set и std::map являются ассоциативными контейнерами. Разница в том, что std::set s содержит только ключ, тогда как в std::map есть связанное значение. Выбор одного над другим зависит в основном от того, что под рукой. Если вы хотите создать словарь всех слов, которые появляются в тексте, вы можете использовать std::set<std::string>, но если вы также хотите подсчитать, сколько раз каждое слово появлялось (т. Е. Связывало значение с ключом), тогда вам понадобится std::map<std::string,int>. Если вам не нужно связывать этот счет, нет смысла иметь ненужный int.

+0

Спасибо вам большое, это все, что мне нужно знать – brunodd

+0

Если вы хотите проверить, существует ли значение в 'set', так же быстро, как проверить, существует ли ключ в' map'? – thomthom

+0

@thomthom: Требования одинаковы, и большинство реализаций используют одну и ту же базовую структуру данных (RB-tree), поэтому ответ заключается в том, что как с теоретической точки, так и на практике стоимость одна и та же. –

1

Это относится к гарантиям сложности, которые наиболее желательны для вашего применения, в отношении вставки, удаления, извлечения и т. Д. Я настоятельно рекомендую Эффективный STL Скотта Мейерса.

2
  • vector быстрее для вставок и удалений в задней части контейнера. Вы можете получить доступ к элементам через оператор [].
  • dequeue похож на vector, но имеет переднюю вставку и удаление.
  • set имеет только ключ, а map имеет pair. Оба этих контейнера быстрее вставляются и удаляются в середине контейнера. Вы также можете получить доступ к элементам через find с помощью алгоритмов STL.
21

набор полезен для хранения уникальных вещей, как перечисление для «typeOfFruits»

std::set<typeOfFruits> fruits; 
fruits.insert (banana); 
fruits.insert (apple); 
fruits.insert (pineapple); 

//it's fast to know if my store sells a type of fruit. 
if (fruits.find (pear) == fruits.end()) 
{ std::cout<<"i don't have pear"; } 

карта полезна для хранения уникальных вещей, плюс «значение»

std::map<typeOfFruits, double /*unit price*/> fruits; 
fruits[banana] = 1.05; 
fruits[apple] = 0.85; 
fruits[pineapple] = 3.05; 
//repeating pineapple will replace the old price (value) 
fruits[pineapple] = 3.35; 

//it's fast to know how much a fruit costs. 
std::map<typeOfFruits, double /*unit price*/> itr = fruits.find(pineapple); 
if (itr != fruits.end()) 
{ std::cout<<"pineapples costs: $" <<itr->second; } 

вектор полезен для хранения вещей, где упорядочена последовательность (push_back()). Представьте, что вы просматриваете свои фрукты в кассе, и программа отслеживает это сканирование.

std::vector<typeOfFruits> fruits; 
fruits.push_back(apple); 
fruits.push_back(apple); 
fruits.push_back(apple); 
fruits.push_back(banana); 
fruits.push_back(banana); 
fruits.push_back(pineapple); 
//i scanned 3 apples, 2 bananas and 1 pineapple. 
2

Ни один орган не упомянул факты, которые std::set фактически неизменны. Вы не должны изменять значение какого-либо элемента в нем. std::set не отслеживает изменения, поэтому, когда вы редактируете элемент в нем, вы идете за его спину и, вероятно, измените свой внутренний порядок. Это рискованное поведение. Поэтому используйте std::map, если вы хотите редактировать элементы после помещения их в контейнер. Удостоверьтесь, что вы используете key, чтобы побудить заказ и все, что вам нужно изменить после этого, в value.

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