C ++에 대한 책에서 STL 컨테이너, 특히 STL 및 컨테이너에 대한 섹션을 읽었습니다. 이제 나는 각자의 고유 한 속성을 가지고 있으며 모든 것을 암기하는 것에 가깝습니다 ... 그러나 아직 이해하지 못하는 것은 각 시나리오가 사용되는 시나리오입니다.
설명은 무엇입니까? 예제 코드가 훨씬 선호됩니다.
C ++에 대한 책에서 STL 컨테이너, 특히 STL 및 컨테이너에 대한 섹션을 읽었습니다. 이제 나는 각자의 고유 한 속성을 가지고 있으며 모든 것을 암기하는 것에 가깝습니다 ... 그러나 아직 이해하지 못하는 것은 각 시나리오가 사용되는 시나리오입니다.
설명은 무엇입니까? 예제 코드가 훨씬 선호됩니다.
답변:
이 치트 시트 는 다른 컨테이너에 대한 요약을 제공합니다.
다른 사용 시나리오에서 사용하기위한 가이드로 하단의 플로우 차트를 참조하십시오.
만든 데이비드 무어 와 BY-SA 3.0 CC 라이센스
vector
비어 있어야합니다 . stackoverflow.com/questions/10699265/…
unordered_map
와 unordered_set
(과 멀티 변종) 흐름도에없는하지만 당신은 순서 만 키로 요소를 찾을 필요가 걱정하지 않을 때 좋은 종목이다. 조회는 일반적으로 O (log n) 대신 O (1)입니다.
다음은 내가 만든 David Moore의 버전 (위 참조)에서 영감을 얻은 순서도이며 새로운 표준 (C ++ 11)으로 최신 상태입니다. 이것은 내 개인적인 취향이며 논쟁의 여지가 없지만이 토론에 가치가 있다고 생각했습니다.
vector (sorted)
나머지 부분과 약간 일치하지 않는다고 생각 합니다. 다른 유형의 컨테이너가 아니라 동일 std::vector
하지만 정렬되었습니다. 더 중요한 것은, 이것이 std::set
트로프 세트를 반복하는 표준 동작 인 경우 왜 순서 반복에 대해을 사용할 수 없는지 알 수 없습니다 . 물론, 대답이 컨테이너 트로프의 값에 순서대로 액세스하는 것에 대해 이야기하고 있다면 []
괜찮습니다 std::vector
. 그러나 두 경우 모두 "주문이 필요합니다"라는 질문 직후에 결정해야합니다.
간단한 대답 : std::vector
달리 할 특별한 이유가 없다면 모든 것을 사용하십시오 .
"Gee, std::vector
X 때문에 여기에서 잘 작동하지 않습니다 "라고 생각하는 경우를 찾으면 X를 기준으로하십시오.
std::remove_if
은 "반복 중 삭제"접근 방식보다 거의 항상 우수합니다.
Scott Meyers의 Effective STL을보십시오. STL 사용법을 잘 설명합니다.
결정되거나 결정되지 않은 수의 객체를 저장하고 절대 삭제하지 않으려는 경우 벡터가 원하는 것입니다. C 배열의 기본 대체이며 하나처럼 작동하지만 오버플로하지는 않습니다. reserve ()를 사용하여 크기를 미리 설정할 수 있습니다.
결정되지 않은 수의 객체를 저장하고 싶지만 객체를 추가하고 삭제하려는 경우 벡터와 달리 다음 요소를 이동하지 않고 요소를 삭제할 수 있기 때문에 목록을 원할 것입니다. 그러나 벡터보다 많은 메모리가 필요하며 요소에 순차적으로 액세스 할 수 없습니다.
많은 요소를 가져 와서 해당 요소의 고유 한 값만 찾으려면 모두 한 세트로 읽으면 정렬되어 정렬됩니다.
키-값 쌍이 많고 키별로 정렬하려면 맵이 유용하지만 키당 하나의 값만 보유합니다. 키당 하나 이상의 값이 필요한 경우 맵에서 값으로 벡터 / 목록을 만들거나 멀티 맵을 사용할 수 있습니다.
STL에는 없지만 STL에 대한 TR1 업데이트에 있습니다. 키별로 조회 할 키-값 쌍이 많고 순서에 신경 쓰지 않으면 tr1 :: unordered_map 인 해시를 사용하고 싶습니다. stdext :: hash_map이라는 Visual C ++ 7.1과 함께 사용했습니다. 맵에 대한 O (log n) 조회 대신 O (1) 조회가 있습니다.
hash_map
구현이 좋지 않다는 몇 가지 일화를 들었습니다 . 나는 그들이 더 잘했으면 좋겠다 unordered_map
.
list
입니다. 오히려 눈부신 오류가 있습니다.
간략하게 만 지금까지 언급 한 중요한 점은, (C 배열은 제공 등)이 연속 메모리를 필요로하는 경우에, 당신 만 사용할 수 있다는 것입니다 vector
, array
또는 string
.
array
컴파일 타임에 크기를 알고있는 경우 사용하십시오 .
string
문자 컨테이너로만 작업하고 범용 컨테이너가 아닌 문자열이 필요한 경우에 사용하십시오 .
vector
다른 모든 경우에 사용하십시오 ( vector
대부분의 경우 컨테이너의 기본 선택이어야 함).
이 세 가지를 모두 사용하면 data()
멤버 함수를 사용 하여 컨테이너의 첫 번째 요소에 대한 포인터를 얻을 수 있습니다 .
모두 저장하려는 내용과 컨테이너로 수행하려는 내용에 따라 다릅니다. 가장 많이 사용하는 컨테이너 클래스에 대한 몇 가지 (매우 철저하지 않은) 예제는 다음과 같습니다.
vector
: 포함 된 객체 당 메모리 오버 헤드가 거의 또는 전혀없는 컴팩트 한 레이아웃. 반복하기에 효율적입니다. 추가, 삽입 및 지우기는 특히 복잡한 개체의 경우 비용이 많이들 수 있습니다. 색인으로 포함 된 객체를 찾는 것이 저렴합니다 (예 : myVector [10]). C에서 배열을 사용한 위치를 사용하십시오. 간단한 객체가 많은 곳 (예 : int)에 좋습니다. reserve()
컨테이너에 많은 객체를 추가하기 전에 사용하는 것을 잊지 마십시오 .
list
: 포함 된 객체 당 작은 메모리 오버 헤드. 반복하기에 효율적입니다. 추가, 삽입 및 삭제가 저렴합니다. C에서 링크 된 목록을 사용한 위치를 사용하십시오.
set
(및 multiset
) : 포함 된 객체 당 상당한 메모리 오버 헤드. 컨테이너에 지정된 객체가 포함되어 있는지 빠르게 확인하거나 컨테이너를 효율적으로 병합해야하는 위치에서 사용하십시오.
map
(및 multimap
) : 포함 된 객체 당 상당한 메모리 오버 헤드. 키-값 쌍을 저장하려는 위치를 사용하고 키별로 값을 빠르게 검색하십시오.
온 흐름도 컨닝 페이퍼 zdan 제안은보다 포괄적 인 가이드를 제공합니다.
내가 배운 한 가지 교훈은 다음과 같습니다. 컨테이너 유형을 좋은 날로 변경하면 큰 놀라움을 줄 수 있기 때문에 클래스로 포장하십시오.
class CollectionOfFoo {
Collection<Foo*> foos;
.. delegate methods specifically
}
초기 비용이 많이 들지 않으며 누군가이 구조에서 x 작업을 수행 할 때마다 중단하고 싶을 때 디버깅 시간을 절약합니다.
작업을위한 완벽한 데이터 구조를 선택합니다.
각 데이터 구조는 몇 가지 작업을 제공하며 시간이 다양 할 수 있습니다.
O (1), O (lg N), O (N) 등
기본적으로 어떤 연산이 가장 많이 수행되는지 가장 잘 추측해야하며 해당 연산이 O (1) 인 데이터 구조를 사용해야합니다.
간단하지 않습니까 (-:
auto myIterator = whateverCollection.begin(); // <-- immune to changes of container type
typedef Collection<Foo*> CollectionOfFoo;
충분?
Mikael Persson의 환상적인 순서도를 확장했습니다 . 컨테이너 범주, 배열 컨테이너 및 메모를 추가했습니다. 자신의 사본을 원한다면 여기 에 Google 드로잉이 있습니다. 기초 작업을 수행 한 Mikael에게 감사합니다! C ++ 컨테이너 피커
나는이 질문의 dup으로 표시된 다른 질문에 이것을 대답했습니다. 그러나 표준 컨테이너를 선택하기로 한 결정에 관한 좋은 기사를 참조하는 것이 좋습니다.
@David Thornley가 대답했듯이 std :: vector는 다른 특별한 요구가 없다면 갈 길입니다. 이것은 C ++ 개발자 인 Bjarne Stroustrup이 2014 년 블로그에서 제공 한 조언입니다.
기사 https://isocpp.org/blog/2014/06/stroustrup-lists에 대한 링크는 다음과 같습니다.
그 말에서 인용하면
그리고 예, 기본적으로 std :: vector를 사용하는 것이 좋습니다.
의견에서 @NathanOliver 사용자는 더 구체적인 측정을 제공하는 또 다른 좋은 블로그를 제공합니다. https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html .