Преимущества std :: set по сравнению с векторами или картами

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

38

Решение

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

57

Другие решения

набор полезен для хранения уникальных вещей, таких как enum для «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.
21

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

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

2

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

1
По вопросам рекламы [email protected]