[C++] 📂. vector
std::vector<T
> 컨테이너
- 크기가 동적인 배열이다.
- 컨테이너 끝에서 원소를 추가/삭제 할 때 효율적이다.
- Random Access를 제공한다.
0. capacity와 size
capacity
(용량,vector<T>::size_type
): 메모리를 추가 할당하지 않아도 저장할 수 있는 원소들의 개수size
(크기,vector<T>::size_type
): 실제로 갖고 있는 원소들의 개수vec.reserve(n); // capacity를 n으로 설정 // vec의 capacity가 n보다 크거나 같다면(<=) 변화 없다. // capacity가 증가하면 주소가 바뀌었기 때문에 기존의 iterator는 무효화된다. // capacity는 log증가 알고리즘을 사용한다.
1. 생성하기
#include <vector>
std::vector<T> vec; // 선언 (capacity:0, size:0)
// vec의 첫 번째 데이터를 추가할 때 메모리가 할당된다.
std::vector<T> vec(n); // 0으로 초기화된 원소 n개 생성
std::vector<T> vec(n, t); // t로 초기화된 원소 n개 생성
std::vector<T> vec {t1, t2, t3}; // t1, t2, t3로 초기화된 벡터 생성 (capacity:3, size:3)
std::array<T, 5> arr {t1, t2, t3, t4, t5};
std::vector<T> copy_vec {std::begin(arr), std::end(arr)}; // array를 복사하여 생성
std::vector<T> move_vec {make_move_iterator(std::begin(arr)), make_move_iterator(std::end(arr))}; // array를 이동하여 생성(이동 반복자)
생성하기 테스트 🔍
- vec.capacity(), vec.size()의 관계
size: 0, capacity: 0 // 생성 size: 1, capacity: 1 size: 2, capacity: 2 size: 3, capacity: 3 size: 4, capacity: 4 size: 5, capacity: 6 size: 6, capacity: 6 size: 7, capacity: 9 size: 8, capacity: 9 size: 9, capacity: 9 size: 10, capacity: 13 size: 11, capacity: 13 size: 12, capacity: 13 size: 13, capacity: 13 size: 14, capacity: 19 size: 15, capacity: 19 size: 16, capacity: 19 size: 17, capacity: 19 size: 18, capacity: 19 size: 19, capacity: 19 size: 20, capacity: 28 size: 21, capacity: 28 size: 22, capacity: 28 size: 23, capacity: 28 size: 24, capacity: 28 size: 25, capacity: 28 size: 26, capacity: 28 size: 27, capacity: 28 size: 28, capacity: 28 size: 29, capacity: 42 size: 30, capacity: 42 size: 31, capacity: 42 size: 32, capacity: 42 size: 33, capacity: 42 size: 34, capacity: 42 size: 35, capacity: 42 size: 36, capacity: 42 size: 37, capacity: 42 size: 38, capacity: 42 size: 39, capacity: 42 size: 40, capacity: 42 size: 41, capacity: 42 size: 42, capacity: 42 size: 43, capacity: 63 size: 44, capacity: 63 size: 45, capacity: 63 size: 46, capacity: 63 size: 47, capacity: 63 size: 48, capacity: 63 size: 49, capacity: 63 size: 50, capacity: 63
- make_move_iterator
(/* 공부 후 추가*/)
2. 접근하기
T front = vec.front(); // 첫 번째 원소의 참조값
T back = vec.back(); // 마지막 원소의 참조값
T value = vec[index]; // index의 원소의 참조값
T* data = vec.data(); // 원소를 저장하는 배열에 대한 포인터
3. 반복자(Iterator)
#include <iterator>
// 1. input
std::copy(std::istream_iterator<T>(std::cin), std::istream_iterator<T>(), std::back_iterator(vec));
// 2. output
std::copy(std::begin(vec), std::end(vec), std::ostream_iterator<T>(std::cout, " "));
4. 원소 삽입하기
// 맨 뒤에 객체(t) 삽입
vec.push_back(t); // 객제(t)를 별도로 생성하여 인수도 전달 (추가 이동연산 필요, r-value 참조)
vec.emplace_back(t); // 내부에서 객체(t)를 바로 생성 (내부에 생성자로 생성, push_back보다 효율적이다.)
- vector는 끝이 아닌 위치에 값을 삽입하는 모든 작업은
부하
가 있다.
vec.emplace(삽입위치 iter, t); // 원하는 위치에 객체(t)를 삽입
vec.insert(삽입위치 iter, t); // 원하는 위치에 객체(t)를 삽입
T t_arr[] {t1, t2, t3, t4};
vec.insert(삽입위치 iter, std::begin(t_arr), std::end(t_arr)); // 순차열 삽입
vec.insert(삽입위치 iter, count, t); // t를 count개 만큼 삽입
vec.insert(삽입위치 iter, {t1, t2, t3, t4}); // 초기화 리스트로 삽입
5. 원소 삭제하기
vec.clear(); // 원소 전체 삭제 (size:0, capacity:그대로)
vec.pop_back(); // 마지막 원소 삭제
// 중간의 원소 삭제
std::swap(삭제원소 iter, std::end(vec)-1);
vec.pop_back();
vec.erase(삭제위치 iter); // 원하는 위치의 객체 삭제
vec.erase(시작위치 iter, 끝+1위치 iter); // 원하는 범위의 객체 삭제
// erase-remove idiom
auto iter = std::remove(std::begin(vec), std::end(vec). t); // vec에서 t와 같은 원소 삭제
vec.erase(iter, std::end(vec)); // 잉여 원소 삭제 (remove에서 삭제된 객체는 빈 객체로 존재한다.)
vec.shrink_to_fit(); // 원소에 필요한 만큼 capacity를 줄인다. (이전 반복자는 무효화 된다.)
댓글남기기