효과적인 STL에서
벡터는 기본적으로 사용해야하는 시퀀스 유형입니다.
무슨 뜻입니까? 효율성을 무시하면 vector
아무것도 할 수 없는 것 같습니다 .
아무도 vector
실현 가능한 옵션이 아니지만 list
사용해야 하는 시나리오를 제공 할 수 있습니까?
효과적인 STL에서
벡터는 기본적으로 사용해야하는 시퀀스 유형입니다.
무슨 뜻입니까? 효율성을 무시하면 vector
아무것도 할 수 없는 것 같습니다 .
아무도 vector
실현 가능한 옵션이 아니지만 list
사용해야 하는 시나리오를 제공 할 수 있습니까?
답변:
시퀀스의 끝을 제외한 모든 위치에 반복적으로 많은 항목을 삽입하려는 상황.
각기 다른 유형의 컨테이너에 대한 복잡성 보장을 확인하십시오.
list
이push_front
벡터:
명부:
일반적으로 사용중인 순차 컨테이너 유형에 신경 쓰지 않을 때 벡터를 사용하지만 컨테이너 이외의 다른 곳에서 많은 삽입 또는 삭제를 수행하는 경우 벡터를 사용하십시오. 목록을 사용하십시오. 또는 임의 액세스가 필요한 경우 목록이 아닌 벡터를 원할 것입니다. 그 외에는 응용 프로그램에 따라 자연스럽게 하나 또는 다른 것이 필요한 경우가 있지만 일반적으로 좋은 지침입니다.
reserve()
이를 O (1)로 줄이기 위해 호출 할 수 있습니다 . 목록에 새 항목을 추가하면 (즉, 연결하지 않음) O (n) 무료 저장소 할당이 수행됩니다.
list
요소를 지울 때 메모리 를 비우지 만 vector
그렇지는 않습니다. 트릭 vector
을 사용하지 않는 한 A 는 크기를 줄일 때 용량을 줄이지 않습니다 swap()
.
여기에있는 대부분의 답변에는 중요한 세부 사항이 하나 없습니다.
컨테이너에 무엇을 보관하고 싶습니까?
int
s 모음 인 std::list
경우 재 할당 할 수 있는지 여부에 관계없이 모든 시나리오에서 잃어 버릴 수 있습니다. 앞면에서만 제거합니다. list<int>
뛰는 예제를 준비하는 것은 매우 어려울 것 vector<int>
입니다. 그리고 그렇다하더라도, deque<int>
크지 메모리 오버 헤드를해야합니다 목록의 사용을 justyfing, 더 나은 또는 가까운 수 있습니다.
그러나 대량의 추악한 데이터를 처리하고 그중 일부를 처리하는 경우 재 할당으로 인해 삽입 및 복사 할 때 전체적으로 할당하지 않으려는 경우 재앙이 될 수 있습니다. list<UglyBlob>
보다 vector<UglyBlob>
.
그래도 vector<UglyBlob*>
또는로 전환하면 vector<shared_ptr<UglyBlob> >
다시-목록이 뒤쳐집니다.
따라서 액세스 패턴, 대상 요소 수 등은 여전히 비교에 영향을 미치지 만 내 견해로는 요소 크기-복사 비용 등이 있습니다.
list<T>
에 대한 가능성 splice
에 O (1) . 일정한 시간의 접속이 필요한 경우,리스트는 선택의 구조 일 수도 있습니다;)
UglyBlob
문자열 멤버가 몇 개인 개체라도 복사 비용이 매우 비싸기 때문에 재 할당 비용 이 많이 듭니다. 또한 : vector
수십 바이트 크기 의 보유 객체가 기하 급수적으로 증가 할 수있는 공간 오버 헤드를 무시하지 마십시오 ( reserve
미리 할 수없는 경우 ).
vector<smart_ptr<Large>>
대 list<Large>
- 난 당신이 요소에 랜덤 액세스가 필요한 경우는,라고 말하고 싶지만 vector
의미가 있습니다. 임의 액세스가 필요하지 않은 경우에는 list
더 단순 해 보이며 동일하게 수행됩니다.
std :: list의 특별한 기능 중 하나는 스 플라이 싱 (일부 또는 전체 목록을 링크하거나 다른 목록으로 이동)입니다.
또는 내용이 복사하는 데 비용이 많이 드는 경우 일 수 있습니다. 이러한 경우 컬렉션을 목록으로 정렬하는 것이 더 저렴할 수 있습니다.
또한 모음이 작고 내용을 복사하는 데 비용이 많이 들지 않으면 어디에서나 삽입하고 지우더라도 벡터가 여전히 목록보다 성능이 우수 할 수 있습니다. 목록은 각 노드를 개별적으로 할당하며 몇 개의 간단한 객체를 옮기는 것보다 비용이 많이들 수 있습니다.
나는 매우 어려운 규칙이 있다고 생각하지 않습니다. 컨테이너와 관련하여 주로 수행하려는 작업과 컨테이너의 크기 및 포함 된 유형에 따라 다릅니다. 벡터는 일반적으로 그 내용을 단일 연속 블록으로 할당하기 때문에 목록보다 우선합니다 (기본적으로 동적으로 할당 된 배열이며 대부분의 경우 배열은 많은 것들을 보유하는 가장 효율적인 방법입니다).
list::size
반드시 일정한 시간은 아닙니다. 참조 stackoverflow.com/questions/228908/is-listsize-really-on 및 gcc.gnu.org/ml/libstdc++/2005-11/msg00219.html
splice
에서 다른 목록 간의 시퀀스 는 선형 복잡도로 지정되며 size
특히 일정합니다. 따라서 반복하는 초보자를 수용 size
하기 위해 STL 또는 "호환되는"컨테이너 기간 동안 전체 알고리즘 클래스에 도달 할 수 없습니다.
글쎄, 내 수업의 학생들은 벡터를 사용하는 것이 더 효과적 일 때 나에게 설명 할 수없는 것처럼 보이지만 목록을 사용하도록 조언 할 때 그들은 매우 행복해 보입니다.
이것이 내가 이해하는 방법입니다
목록 : 각 항목에는 다음 또는 이전 요소에 대한 주소가 포함되어 있으므로이 기능을 사용하면 정렬되지 않아도 항목을 무작위로 지정할 수 있습니다. 순서가 변경되지 않습니다. 메모리가 조각난 경우 효율적입니다. 그러나 또 다른 큰 장점이 있습니다. 포인터를 변경하면 항목을 쉽게 삽입 / 제거 할 수 있습니다. 단점 : 임의의 단일 항목을 읽으려면 올바른 주소를 찾을 때까지 한 항목에서 다른 항목으로 이동해야합니다.
벡터 : 벡터를 사용할 때 메모리는 일반 배열처럼 훨씬 더 체계적으로 구성됩니다. 각 n 번째 항목은 (n-1) 번째 항목 바로 뒤에 그리고 (n + 1) 번째 항목 앞에 저장됩니다. 왜 목록보다 낫습니까? 빠른 임의 액세스를 허용하기 때문입니다. 방법은 다음과 같습니다. 벡터에서 항목의 크기를 알고 메모리에서 연속적인 경우 n 번째 항목의 위치를 쉽게 예측할 수 있습니다. 원하는 항목을 읽기 위해 목록의 모든 항목을 찾아 볼 필요는 없습니다. 벡터를 사용하면 목록을 직접 읽을 수없고 목록을 읽을 수 없습니다. 반면에 벡터 배열을 수정하거나 값을 변경하면 속도가 훨씬 느려집니다.
메모리에 추가 / 제거 할 수있는 개체를 추적하는 데 목록이 더 적합합니다. 대량의 단일 항목에서 요소에 액세스하려는 경우 벡터가 더 적합합니다.
목록이 어떻게 최적화되는지는 모르겠지만 빠른 읽기 액세스를 원한다면 벡터를 사용해야합니다 .STL이 목록을 얼마나 잘 작성하면 벡터보다 읽기 액세스가 빠르지 않기 때문입니다.
vector
reserve()
기본적으로 벡터는 자동 메모리 관리 기능이있는 배열입니다. 데이터가 메모리에 인접 해 있습니다. 중간에 데이터를 삽입하는 것은 비용이 많이 드는 작업입니다.
목록에서 데이터는 관련없는 메모리 위치에 저장됩니다. 중간에 삽입하는 것은 새로운 데이터를위한 공간을 만들기 위해 일부 데이터를 복사하는 것을 포함하지 않습니다.
더 구체적으로 귀하의 질문에 대답하기 위해이 페이지를 인용 하겠습니다
벡터는 일반적으로 요소에 액세스하고 시퀀스의 끝에서 요소를 추가하거나 제거하는 데 가장 효율적입니다. 끝 이외의 위치에 요소를 삽입하거나 제거하는 작업의 경우 deques 및 list보다 성능이 저하되고 목록보다 일관된 반복자 및 참조가 적습니다.
시퀀스 중간에 많은 삽입 또는 삭제가있는 경우 예를 들어 메모리 관리자.
컨테이너간에 객체를 이동하려면을 사용할 수 있습니다 list::splice
.
예를 들어, 그래프 분할 알고리즘은 증가하는 수의 컨테이너 사이에 일정한 수의 객체를 재귀 적으로 나눌 수있다. 객체는 한 번 초기화되고 항상 메모리의 동일한 위치에 유지되어야합니다. 재 할당보다 재 링크하여 재배 열하는 것이 훨씬 빠릅니다.
편집 : 라이브러리가 C ++ 0x를 구현할 준비를 할 때 하위 시퀀스를 목록에 스 플라이 싱하는 일반적인 경우는 시퀀스 길이에 따라 선형 적으로 복잡해지고 있습니다. 그 이유는 splice
현재 요소의 수를 계산하기 위해 시퀀스를 반복해야하기 때문입니다. (목록의 크기를 기록해야하기 때문에) 단순히 목록을 계산하고 다시 연결하는 것이 여전히 다른 방법보다 빠르며 전체 목록 또는 단일 요소를 연결하는 것은 지속적인 복잡성을 가진 특수한 경우입니다. 그러나 결합 할 시퀀스가 긴 경우 더 나은 구식 비준수 컨테이너를 찾아야합니다.
간단하게
-C ++에서 컨테이너를 선택하는 것이 혼란 스러울 때이 흐름도 이미지를 사용하십시오 (저에게 감사하십시오) :-
여기에 이미지 설명을 입력하십시오
벡터
-1. 벡터는
전염성 메모리를 기반으로합니다
. 2. 벡터는 작은 데이터 세트로가는 길입니다
3. 벡터는 데이터 세트를 순회하는 동안 가장 빠르게 수행됩니다
. 4. 벡터 삽입 삭제는 거대한 데이터 세트에서 느리지 만 매우 작은 경우에는 빠릅니다.
- 온라인
1. 목록이 힙 메모리를 기반으로
2. 목록은 매우 큰 데이터 세트에 대한 갈 방법은
3. 목록 거대한 데이터 세트에서 빠른 작은 데이터 세트 만 횡단에 느린 비교적 인
에 빠른 4. 목록 삽입 삭제됩니다 거대한 데이터 세트이지만 작은 데이터 세트에서는 느립니다.
벡터 와 리스트 의 경우 나에게 튀어 나오는 주요 차이점은 다음과 같습니다.
벡터
벡터는 해당 요소를 연속 메모리에 저장합니다. 따라서 벡터 내에서 임의 액세스가 가능합니다. 즉, 기본 요소에 항목 인덱스를 곱하여 해당 요소에 액세스하기 때문에 벡터 요소에 액세스하는 것이 매우 빠릅니다. 실제로이 목적을 위해서는 O (1) 또는 일정한 시간 만 걸립니다.
벡터는 기본적으로 배열을 래핑하기 때문에 벡터 (동적 배열)에 요소를 삽입 할 때마다 시간이 많이 걸리는 새로운 요소를 수용 할 수있는 새로운 연속 메모리 블록을 찾아서 크기를 조정해야합니다.
그 안에 다른 요소에 대한 포인터를 저장하는 데 추가 메모리를 소비하지 않습니다.
명부
목록은 비 연속 메모리에 해당 요소를 저장합니다. 따라서 목록 내에서 임의 액세스가 불가능합니다. 즉, 요소에 액세스하려면 포인터를 사용하고 벡터에 비해 느린 목록을 탐색해야합니다. O (n) 또는 선형 시간이 걸리며 O (1)보다 느립니다.
리스트는 비 연속 메모리를 사용하기 때문에, 메모리의 재 할당을 피하기 때문에리스트에 요소를 삽입하는 데 걸리는 시간은 벡터의 경우보다 훨씬 효율적입니다.
특정 요소 전후에 요소에 대한 포인터를 저장하기 위해 추가 메모리를 소비합니다.
따라서 이러한 차이를 염두에두고 주어진 시나리오에서 벡터 대 목록 의 승자를 결정하기 위해 일반적으로 메모리 , 자주 사용하는 임의 액세스 및 삽입 을 고려 합니다 .