В каком сценарии я использую конкретный контейнер STL?
Я читал о контейнерах STL в своей книге на C++, в частности, раздел о STL и его контейнерах. Теперь я понимаю, что у каждого из них есть свои специфические свойства, и я близок к тому, чтобы запомнить их все... Но я пока не понимаю, в каком сценарии используется каждый из них.
каково объяснение? Пример кода гораздо предпочтительнее.
8 ответов:
это шпаргалка обеспечивает довольно хорошее резюме различных контейнеров.
см. блок-схему внизу в качестве руководства для использования в различных сценариях использования:
создано Дэвид Мур и лицензионный CC BY-SA 3.0
вот блок-схема, вдохновленная версией Дэвида Мура (см. выше), которую я создал, которая обновлена (в основном) с новым стандартом (C++11). Это только мой личный взгляд на это, это не бесспорно, но я подумал, что это может быть полезно для этого обсуждения:
простой ответ: используйте vector для всего, если у вас нет реальной причины поступать иначе.
когда вы находите случай, когда вы думаете: "Gee, vector не работает хорошо здесь из-за X", идите на основе X.
смотреть на эффективное использование STL Скотт Мейерс. Это хорошо объясняет, как использовать STL.
Если вы хотите сохранить определенное/неопределенное количество объектов, и вы никогда не собираетесь удалять, то вектор является то, что вы хотите. Это замена по умолчанию для массива C, и он работает как один, но не переполнение. Вы можете установить его размер заранее, а также с резервом ().
Если вы хотите хранить неопределенное количество объектов, но вы будете добавлять их и удалив их, вы, вероятно, хотите получить список...потому что вы можете удалить элемент без перемещения каких-либо следующих элементов - в отличие от вектора. Однако для этого требуется больше памяти, чем вектор, и вы не можете последовательно обращаться к элементу.
Если вы хотите взять кучу элементов и найти только уникальные значения этих элементов, чтение их всех в набор сделает это, и он будет сортировать их для вас.
Если у вас много пар ключ-значение, и вы хотите отсортировать их по ключ, то карта полезна...но он будет содержать только одно значение на один ключ. Если вам нужно более одного значения на ключ, вы можете иметь вектор/список в качестве значения на карте или использовать multimap.
Это не в STL, но это в обновлении TR1 для STL: если у вас есть много пар ключ-значение, которые вы собираетесь искать по ключу, и вы не заботитесь об их порядке, вы можете использовать хэш - который является tr1::unordered_map. Я использовал его с Visual C++ 7.1, где он был вызван stdext:: hash_map. Он имеет поиск O(1) вместо поиска O (log n) для map.
все зависит от того, что вы хотите хранить и что вы хотите сделать с контейнером. Вот некоторые (очень неисчерпывающие) примеры для классов контейнеров, которые я обычно использую:
vector
: компактная компоновка с минимальными или нулевыми затратами памяти на каждый содержащийся объект. Эффективный для итерации. Добавление, вставка и стирание могут быть дорогостоящими, особенно для сложных объектов. Дешево найти содержащий объект по индексу, например myVector[10]. Используйте там, где вы бы использовали массив в C. Хорошо, когда у вас есть много простых объектов (например, int). Не забудьте использоватьreserve()
перед добавлением большого количества объектов в контейнер.
list
: небольшие накладные расходы памяти на один содержащийся объект. Эффективный для итерации. Добавить, вставить и стереть дешево. Используйте там, где вы бы использовали связанный список в C.
set
(иmultiset
): значительные затраты памяти на каждый содержащийся объект. Используйте там, где вам нужно быстро узнать, содержит ли этот контейнер данный объект, или эффективное слияние контейнеров.
map
(иmultimap
): значительные затраты памяти на каждый содержащийся объект. Используйте там, где вы хотите хранить пары ключ-значение и быстро искать значения по ключу.на схеме шпаргалка предложенный здан обеспечивает более исчерпывающее руководство.
важный момент, только кратко упомянутый до сих пор, заключается в том, что если вам требуется непрерывная память (например, массив C дает), то вы можете использовать только
vector
,array
илиstring
.использовать
array
если размер известен во время компиляции.использовать
string
Если вам нужно работать только с символьными типами и нужна строка, а не просто контейнер общего назначения.использовать
vector
во всех остальных случаях (vector
должен быть выбор контейнера по умолчанию в большинстве случаев в любом случае.)со всеми тремя из них вы можете использовать
data()
функция-член, чтобы получить указатель на первый элемент контейнера.
один урок, который я узнал: попробуйте обернуть его в класс, так как изменение типа контейнера в один прекрасный день может привести к большим сюрпризам.
class CollectionOfFoo { Collection<Foo*> foos; .. delegate methods specifically }
это не стоит много вперед, и экономит время в отладке, когда вы хотите, чтобы сломать всякий раз, когда кто-то делает операцию x на этой структуре.
переход к выбору идеальной структуры данных для задания:
каждая структура данных обеспечивает некоторые операции, которые могут варьироваться во времени сложность:
O (1), O(lg N), O (N) и др.
вы по существу должны принять лучшее предположение, на котором операции будут выполняться больше всего, и использовать структуру данных, которая имеет эту операцию как O(1).
просто, не так ли (-:
Я остановился на Микаэль Перссон фантастическая схема. Я добавил некоторые категории контейнеров, контейнер массива и некоторые заметки. Если вам нужна ваша собственная копия,здесь Это рисунок Google. Спасибо, Микаэль за проделанную работу! C++ Container Picker