C++/STL

C++ STL 정리 - Vector

728x90

# Definition

template<
    class T,
    class Allocator = std::allocator<T>
> class vector;
cs

벡터는 순차 컨테이너의 한 종류로, 기본적으로 동적으로 메모리가 할당된다.

정의에서 Allocator 란 컨테이너의 메모리를 관리하는 할당자 이다.

(참고 : openmynotepad.tistory.com/57)

 

 

 

# Header

#include <vector>
cs

 

 

# 초기화

// 1. 기본 생성 (할당된 값도 없고 크기도 지정하지 않은 상태)
vector<T> vec;
 
 
// 2 - 1. 크기를 지정해준 일차원 벡터 초기화
vector<int> vec(4);
 
/*
    벡터의 크기가 4 가 되고, 각 원소의 값이 0임 (단, 전역 변수 선언시에만)
    vec = {0, 0, 0, 0}
*/
 
// 2 - 2. fill 로 채운 일차원 벡터 초기화
vector<int> vec(4);
fill(vec.begin(), vec.end(), 0); // algorithm 헤더 필요
 
 
// 3. 값을 지정해준 초기화
vector<int> vec = { 1234};
 
 
// 4. 이차원 벡터 초기화 (열 고정)
vector<int> vec[] = {{0,0}, {0,0}};
 
/*
    열의 크기는 고정, 행의 크기는 변경 가능.
*/
 
 
// 5. 이차원 벡터 초기화 (행과 열 모두 크기 변경 가능)
vector<vector<int>> vec;
 
 
// 이차원 벡터 크기 지정 형태로 초기화
vector<vector<int>> vec(n, vector<int>(n));
 
fill(vec.begin(), vec.end(), vector<int>(00)); // algorithm 헤더 필요
cs

 

 

 

# Iterator

/*
    참조
    https://en.cppreference.com/w/cpp/container/vector/begin
    https://en.cppreference.com/w/cpp/container/vector/begin
    
    1. begin()
    vector 의 시작 지점의 iterator를 반환.
    
    2. end()
    vector 의 끝 지점 + 1 (N + 1) 의 iterator 를 반환
    
    3. rbegin()
    reverse begin 으로 벡터의 끝 지점(N) 을 시작점으로 반환
    
    4.  rend()
    reverse end 로 벡터의 시작지점 -1 을 끝으로 반환
*/
 
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
 
using namespace std;
 
int main() {
 
    vector<int> vec {1,2,3,4,5};    
    vector<string> name {"kim""park""jung"};
    vector<char> empty;
    
    for_each(vec.begin(), vec.end(), [](const int n) { cout << n << ' '; });
    cout << '\n';
    
    cout << "sum of vec : " << accumulate(vec.begin(), vec.end(), 0<< '\n';
    
    if (!name.empty())
        cout << "First name : " << *name.begin() << '\n';
        
    if (empty.begin() == empty.end())
        cout << "vector empty is indeed empty" << '\n';
    
    for_each(vec.rbegin(), vec.rend(), [](const int n) { cout << n << ' ';});
    cout << '\n';
    
    cout << "sum of vec : " << accumulate(vec.rbegin(), vec.rend(), 0<< '\n';
    
    if (!name.empty())
        cout << "First name : " << *name.rbegin() << '\n';
        
    if (empty.rbegin() == empty.rend())
        cout << "vector empty is indeed empty" << '\n';
    
    return 0;
}
cs

 

 

begin, end
rbegin, rend

 

# 벡터 내부 요소 접근

/*
    1. at(i)
    i 번째 요소에 접근하여 값을 리턴
    
    2. front()
    벡터의 첫번째 요소에 접근
    
    3. back()
    벡터의 마지막 요소에 접근
*/
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    vector<int> vec {1,2,3,4};
    cout << vec.front() << '\n'// 1 이 출력
    cout << vec.back() << '\n';  // 4 가 출력
    cout << v.at(2<< '\n';     // 3 이 출력
    return 0;
}
cs

 

 

# 요소 삽입, 삭제, 수정

/*
    1. push_back();
    벡터의 마지막 부분에 새 원소를 추가.
    
    2. pop_back();
    벡터의 마지막 부분 제거
    
    3. insert(주소값, 변수값)
    원하는 주소값에 변수값을 삽입
    
    4. emplace(주소값, 변수값)
    insert 와 기능은 같으나 복사생성자가 발생하지 않음
    
    5. emplace_back()
    벡터의 마지막 부분에 요소 추가
    
    6. erase(위치) 또는 erase(시작위치, 끝위치)
    원하는 위치의 값 제거
    
    7. clear()
    모두 제거
    
    8. resize()
    벡터 크기 조정
    
    9. swap(벡터)
    벡터와 벡터끼리 swap
*/
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    vector<int> vec;
    
    vec.push_back(1); 
    vec.push_back(2); // vec = {1,2}
    
    vec.insert(vec.begin() + 15); // vec = {1,5,2}
    
    vec.pop_back(); // vec = {1,5}
    
    vec.emplace_back(9); // vec = {1,5,9}
    vec.emplace(vec.begin() + 299); // vec = {1,5,99,9}
    
    vec.erase(vec.begin() + 1); // vec = {1,99,9}
    
    vec.resize(5); // vec = {1,99,9,0,0}
    
    vector<int> vec2 = {888777666555444};
    
    for (int i = 0; i < 5; i++) {
        cout << vec[i] << ' ';
    }
    cout << '\n';
    
    for (int i = 0; i < 5; i++) {
        cout << vec2[i] << ' ';
    }
    cout << '\n';
    
    vec.swap(vec2);
    
    for (int i = 0; i < 5; i++) {
        cout << vec[i] << ' ';
    }
    cout << '\n';
    
    for (int i = 0; i < 5; i++) {
        cout << vec2[i] << ' ';
    }
    cout << '\n';
    
    return 0;
}
cs

 

 

 

# 벡터의 용량 확인

/*
    1. empty()
    벡터가 비었는지 아닌지 판별
    
    2. size()
    벡터의 크기 반환
    
    3. capacity()
    heap 에 할당된 벡터의 실제 크기 반환
    
    4. max_size()
    벡터가 시스템에서 만들어 질 수 있는 최대 크기 반환
    
    5. reverse(숫자)
    벡터의 capacity 설정
    
    6. shrink_to_fit()
    capacity 의 크기를 실제 크기에 맞추기
*/
 
#include <iostream>
#include <vector>
 
using namespace std;
 
int main() {
    int size = 200;
    vector<int> vec;
    
    auto cap = vec.capacity();
    cout << "initial capacity : " << cap << '\n';
    
    for (int i = 0; i < size; i++) {
        vec.push_back(i);
        if (cap != vec.capacity()) {
            cap = vec.capacity();
            cout << "new capacity : " << cap << '\n';
        }
    }
    
    cout << "size : " << vec.size() << '\n';
    cout << "capacity : " << vec.capacity() << '\n';
    
    cout << vec.empty() << '\n';
    cout << vec.max_size() << '\n';
   
    return 0;
}
cs

 

 

 

# 참고

1. size 는 벡터안에 들어간 요소의 갯수를 말하고, capacity 는 벡터가 메모리상에 실제로 할당 받은 메모리 값을 의미.

 

2. push_back 을 해서 원소를 하나씩 넣을 경우, 벡터의 capacity 가 2배씩 증가, 

즉, 넣을때마다 메모리 할당을 해주는 방식

-> 그래서 resize 를 통해서 미리 벡터의 크기를 지정하면 좀 더 연산이 빠르다.

(참고 : https://en.cppreference.com/w/cpp/container/vector/capacity)

 

3. 벡터의 크기를 N 이라고 지정하면 실제로는 맨뒤에 하나더 메모리가 할당. (N + 1)

 

4. capacity 값보다 size 값이 더 크면 내부적으로 재할당 연산을 수행.

재할당을 수행하면 기존의 벡터값은 다른 새로운 메모리에 할당되고, 기존 벡터의 메모리값은 사라짐.

이 복사를 하는 과정에서 복사 생성자를 사용.

그렇기 때문에 size 가 capacity 를 초과할수록 성능의 저하를 일으킴

-> 삽입과 삭제가 자주일어나는 상황이면 list 나 deque 를 쓰는 것이 좋다고한다.

 

 

 

 

-Reference

https://hwan-shell.tistory.com/119

https://en.cppreference.com/w/cpp/container/vector

 

 

 

 

 

728x90

'C++ > STL' 카테고리의 다른 글

C++ STL 정리 - 정렬  (0) 2020.11.15
C++ STL 정리 - Stack  (0) 2020.09.27
C++ STL 정리 - Map  (0) 2020.09.10
C++ STL 정리 - Set  (0) 2020.09.07
C++ STL 정리 - 개요  (0) 2020.08.25