Это может быть глупый вопрос, я довольно плохо знаком с C ++ и программированием в целом.
Я хотел бы понять использование нескольких контейнеров STL, и с учетом этого мне было интересно, каковы преимущества использования std :: set vs, например, с использованием векторов или карт?
Я не могу найти четкий ответ на этот вопрос. Я заметил, что наборы используют карты, но почему бы не всегда использовать карты или всегда использовать наборы. Вместо этого предоставляются 2 очень похожих контейнера.
Заранее спасибо.
И то и другое std::set
а также std::map
являются ассоциативными контейнерами. Разница в том, что std::set
s содержат только ключ, а в std::map
есть связанная ценность. Выбор одного зависит от другого, главным образом, от того, какая задача находится под рукой. Если вы хотите создать словарь из всех слов, которые появляются в тексте, вы можете использовать std::set<std::string>
, но если вы также хотите посчитать, сколько раз появилось каждое слово (то есть связать значение с ключом), вам понадобится std::map<std::string,int>
, Если вам не нужно связывать этот счет, не имеет смысла иметь int
в этом нет необходимости.
набор полезен для хранения уникальных вещей, таких как 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.
vector
быстрее для вставок и удалений в задней части контейнера. Вы можете получить доступ к элементам через оператор [].dequeue
похож на vector
но это показывает переднюю вставку и удаление.set
только ключ пока map
имеет pair
, Оба эти контейнера быстрее для вставки и удаления в середине контейнера. Вы также можете получить доступ к элементам через find с помощью алгоритмов STL.Никто не упомянул факты, которые std::set
на самом деле неизменным. Вы не должны изменять значение любого элемента в нем. std::set
не отслеживает изменения, поэтому, когда вы редактируете элемент в нем, вы идете за его спиной и, скорее всего, измените его внутренний порядок. Это рискованное поведение. Поэтому используйте std::map
если вы хотите редактировать элементы после помещения их в контейнер. Убедитесь, что вы используете key
чтобы вызвать порядок и все, что вам нужно изменить в дальнейшем value
,
Это сводится к гарантиям сложности, которые наиболее желательны для вашего приложения, в отношении вставки, удаления, поиска и т. Д. Я настоятельно рекомендую Эффективный STL Скотта Мейерса.