C++ stl vector 사용법 및 예제 소개

이 글에서는 vector 개념을 탐구하고, vector를 생성하고 초기화하는 방법, 요소에 액세스하고 수정하는 방법, 일반적인 작업 수행 방법 및 일부 고급 기능을 살펴보겠습니다. 이 블로그를 마치면 vector에 대한 탄탄한 이해를 갖게 되며, 여러분의 C++ 프로그램에서 그들의 능력을 활용할 지식을 갖추게 될 것입니다.

STL 이란

STL은 Standard Template Library의 약자입니다. STL은 데이터를 저장하고 처리하는 데 주로 사용하는 일반적인 클래스와 함수의 모음입니다. STL은 컨테이너 클래스, 알고리즘 및 반복자를 포함한 라이브러리로 정의할 수 있으며, C++의 vector 역시 STL의 일부입니다. STL의 주요 아이디어는 이미 작성되고 테스트된 코드를 재사용하는 것입니다. 이로써 시간과 노력을 절약할 수 있습니다.

vector란 무엇인가요?

vector는 STL의 일부입니다. C++의 vector는 런타임 중에 크기를 변경할 수 있는 배열을 나타내는 시퀀스 컨테이너입니다. 배열에서와 마찬가지로 요소에 대해 연속적인 저장 위치를 효율적으로 사용하며, 이는 요소에 대한 일반 포인터의 오프셋을 사용하여 요소에 액세스할 수도 있음을 의미합니다.
vector는 정렬되어 있지 않습니다. 그래서 vector 요소는 인접한 저장소에 배치되며 반복기를 사용하여 쉽게 액세스하고 이동할 수 있습니다.

vector 선언

C++에서 vector를 사용하려면 vector 헤더를 포함해야 합니다.

#include <vector>

vector 선언을 위한 구문은 다음과 같습니다:

vector<객체_타입> vector_변수_이름;

vector 에 값을 넣는 방법

다음 방법들은 vector 에 가장 자주 등장하는 값을 추가 하는 방법입니다.

vector에 값을 하나씩 push_back() 메서드를 사용하여 넣는 것으로 모든 요소를 vector에 저장합니다.

vector_이름.push_back(요소_값);

vector 클래스의 오버로드 생성자를 사용하는 방법도 있습니다. 이 방법은 여러 번 동일한 값으로 vector를 채우는 데 사용됩니다.

vector<객체_타입> vector_이름(반복_횟수, 요소_값);

또한 배열을 사용하는 방법도 있습니다. 배열을 vector 생성자에 전달합니다.

vector<객체_타입> vector_이름 {값1, 값2, 값3, ..., 값n};

기존에 초기화된 vector를 사용하여 새 vector를 생성하는 방법도 있습니다. 이 방법은 이미 초기화된 vector 의 시작과 끝을 전달합니다.

vector<객체_타입> 새로운_vector_이름(기존_vector_이름.begin(), 기존_vector_이름.end());

vector의 다양한 함수

반복자(Iterators):

  • begin() – vector의 첫 번째 요소를 가리키는 반복자를 반환합니다.
  • end() – vector의 마지막 요소를 가리키는 반복자를 반환합니다.
  • rbegin() – vector의 마지막 요소를 가리키는 역반복자를 반환합니다.
  • rend() – vector의 첫 번째 요소 앞을 가리키는 역반복자를 반환합니다.
  • cbegin() – vector의 첫 번째 요소를 가리키는 상수 반복자를 반환합니다.
  • cend() – vector의 마지막 요소 다음을 가리키는 상수 반복자를 반환합니다.
  • crbegin() – vector의 마지막 요소를 가리키는 상수 역반복자를 반환합니다.
  • crend() – vector의 첫 번째 요소 앞을 가리키는 상수 역반복자를 반환합니다.

예시 코드: 반복자 사용 예

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> a; // vector 선언

    // vector 'a'를 값 1부터 7까지 초기화
    for (int i = 1; i <= 7; i++)
        a.push_back(i);

    // begin()과 end() 반복자를 사용하여 vector 'a'의 출력
    cout << "begin과 end 함수 출력: ";
    for (auto i = a.begin(); i != a.end(); ++i)
        cout << *i << " ";

    // cbegin()과 cend() 반복자를 사용하여 vector 'a'의 출력
    cout << "\ncbegin과 cend 함수 출력: ";
    for (auto i = a.cbegin(); i != a.cend(); ++i)
        cout << *i << " ";

    // rbegin()과 rend() 반복자를 사용하여 vector 'a'의 출력
    cout << "\nrbegin과 rend 함수 출력: ";
    for (auto ir = a.rbegin(); ir != a.rend(); ++ir)
        cout << *ir << " ";

    // crbegin()과 crend() 반복자를 사용하여 vector 'a'의 출력
    cout << "\ncrbegin과 crend 함수 출력: ";
    for (auto ir = a.crbegin(); ir != a.crend(); ++ir)
        cout << *ir << " ";

    return 0;
}
output
begin과 end 함수 출력: 1 2 3 4 5 6 7
cbegin과 cend 함수 출력: 1 2 3 4 5 6 7
rbegin과 rend 함수 출력: 7 6 5 4 3 2 1
crbegin과 crend 함수 출력: 7 6 5 4 3 2 1

용량(Capacity):

  • size() – vector에 현재 있는 요소의 수를 반환합니다.
  • max_size() – vector가 보유할 수 있는 최대 요소 수를 반환합니다.
  • capacity() – 현재 할당된 메모리 공간의 용량을 반환합니다.
  • resize(n) – 컨테이너 크기를 ‘n’ 요소를 저장하도록 조정합니다.
  • empty() – 컨테이너가 비어 있는지 여부를 반환합니다.

예시 코드: 용량 함수 사용 예

// 용량 함수 사용 예제
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> a; // 정수형 vector 선언

    // vector 'a'를 값 1부터 5까지 초기화
    for (int i = 1; i <= 5; i++)
        a.push_back(i);

    // vector 'a'의 크기 출력
    cout << "크기: " << a.size();

    // vector 'a'의 용량 출력
    cout << "\n용량: " << a.capacity();

    // vector 'a'의 최대 크기 출력
    cout << "\n최대 크기: " << a.max_size();

    // vector 'a'를 크기 4로 재조정
    a.resize(4);

    // resize() 함수 사용 후 vector 'a'의 크기 출력
    cout << "\nresize() 함수 사용 후 크기: " << a.size();

    // vector가 비어 있는지 여부 확인
    if (!a.empty())
        cout << "\nvector는 비어 있지 않습니다.";
    else
        cout << "\nvector는 비어 있습니다.";

    return 0;
}
output
크기: 5
용량: 6
최대 크기: 4611686018427387903
resize() 함수 사용 후 크기: 4
vector는 비어 있지 않습니다.

수정자(Modifiers):

  • assign() – vector의 기존 요소에 새 값을 할당합니다.
  • push_back() – vector의 뒷부분에 요소를 추가합니다.
  • pop_back() – vector의 뒷부분에서 요소를 제거합니다.
  • insert() – vector에서 특정 요소 앞에 요소를 삽입합니다.
  • erase() – vector에서 특정 요소나 범위의 요소를 제거합니다.
  • swap() – 동일한 데이터 유형의 두 vector의 내용을 교환합니다. vector 크기는 다를 수 있습니다.
  • clear() – vector에서 모든 요소를 제거합니다.

예시 코드: 수정자 함수 사용 예

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    // 정수형 vector 'a' 선언
    vector<int> a;

    // vector 'a'에 값 7을 4번 반복하여 할당
    a.assign(4, 7);

    // vector 'a'의 내용 출력
    cout << "vector 내용: ";
    for (int i = 0; i < a.size(); i++)
        cout << a[i] << " ";

    // vector 'a'의 뒷부분에 10을 추가
    a.push_back(10);
    int n = a.size();
    cout << "\n마지막 요소: " << a[n - 1];

    // vector 'a'에서 마지막 요소 제거
    a.pop_back();

    // vector 'a'의 내용 출력
    cout << "\nvector 내용: ";
    for (int i = 0; i < a.size(); i++)
        cout << a[i] << " ";

    // vector 'a'의 처음에 3을 삽입
    a.insert(a.begin(), 3);

    // vector 'a'의 첫 번째 요소 출력
    cout << "\n첫 번째 요소: " << a[0];

    // vector 'a'에서 첫 번째 요소 제거
    a.erase(a.begin());

    // 제거 후 vector 'a'의 새로운 첫 번째 요소 출력
    cout << "\n첫 번째 요소: " << a[0];

    // vector 'a'를 지움
    a.clear();

    // 지운 후 vector 'a'의 크기 출력
    cout << "\n지운 후 vector 크기: " << a.size();

    // 정수형 vector 'a1'과 'a2' 선언
    vector<int> a1, a2;

    // vector 'a1'과 'a2'에 값 추가
    a1.push_back(3);
    a1.push_back(4);
    a2.push_back(5);
    a2.push_back(6);

    // vector 'a1'과 'a2' 내용 출력
    cout << "\n\nvector 1: ";
    for (int i = 0; i < a1.size(); i++)
        cout << a1[i] << " ";

    cout << "\nvector 2: ";
    for (int i = 0; i < a2.size(); i++)
        cout << a2[i] << " ";

    // vector 'a1'과 'a2'의 내용 교환
    a1.swap(a2);

    // 교환 후 vector 'a1'의 내용 출력
    cout << "\n교환 후 vector 1: ";
    for (int i = 0; i < a1.size(); i++)
        cout << a1[i] << " ";

    // 교환 후 vector 'a2'의 내용 출력
    cout << "\nvector 2: ";
    for (int i = 0; i < a2.size(); i++)
        cout << a2[i] << " ";

    return 0;
}
output

vector 내용: 7 7 7 7
마지막 요소: 10
vector 내용: 7 7 7 7
첫 번째 요소: 3
첫 번째 요소: 7
지운 후 vector 크기: 0

vector 1: 3 4
vector 2: 5 6
교환 후 vector 1: 5 6
vector 2: 3 4

요소 접근(Element access):

  • reference_operator[g] – vector의 ‘g’ 번째 요소에 대한 참조를 반환합니다.
  • at(g) – vector에서 ‘g’ 위치의 요소에 대한 참조를 반환합니다.
  • front() – vector의 첫 번째 요소에 대한 참조를 반환합니다.
  • back() – vector의 마지막 요소에 대한 참조를 반환합니다.
  • data() – vector가 소유한 요소를 저장하는 데 내부적으로 사용하는 메모리 배열에 대한 직접 포인터를 반환합니다.

예시 코드: 요소 접근 함수 사용 예

// 요소 접근 함수 사용 예제
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    // 정수형 vector 'a' 선언
    vector<int> a;

    // vector 'a'에 10부터 100까지 값을 추가
    for (int i = 1; i <= 10; i++)
        a.push_back(i * 10);

    // 참조 연산자를 사용하여 vector 'a'의 세 번째 요소 출력
    cout << "\n참조 연산자 [g]: a[2] = " << a[2];

    // at 함수를 사용하여 vector 'a'의 인덱스 4의 요소 출력
    cout << "\nat 함수: a.at(4) = " << a.at(4);

    // front 함수를 사용하여 vector 'a'의 첫 번째 요소 출력
    cout << "\nfront 함수: a.front() = " << a.front();

    // back 함수를 사용하여 vector 'a'의 마지막 요소 출력
    cout << "\nback 함수: a.back() = " << a.back();

    // data 함수를 사용하여 vector의 첫 번째 요소에 대한 포인터 출력
    int* pos = a.data();
    cout << "\n첫 번째 요소: " << *pos;

    return 0;
}
output
참조 연산자 [g]: a[2] = 30
at 함수: a.at(4) = 50
front 함수: a.front() = 10
back 함수: a.back() = 100
첫 번째 요소: 10

vector에서 사용하는 할당자 함수

할당자는 동적으로 메모리를 할당하고 해제하는 객체입니다. C++ vector에서는 할당자 함수 중 하나인 get_allocator() 함수를 사용합니다. 이 함수는 vector와 관련된 할당자 객체의 사본을 반환합니다.

vector 사용 시 고려사항

  • 데이터가 지속적으로 변경되는 경우 vector를 사용하는 것이 좋습니다.
  • 데이터 크기가 알려지지 않은 경우 vector를 사용하는 것이 좋습니다.
  • 요소가 미리 정의되지 않은 경우 vector를 사용하는 것이 좋습니다.
  • vector는 다른 vector로 복사하는 방법이 더 다양합니다.

배열과 vector 비교

  • 배열은 순차 컨테이너이며 인덱스 기반입니다.
  • vector는 동적입니다.
  • 배열은 초기화된 후 크기를 변경할 수 없습니다.
  • 배열은 메모리를 효율적으로 사용합니다.
  • 배열은 요소에 대한 액세스 시 상수 시간이 걸립니다.
  • vector는 C++에서만 선언할 수 있지만 배열은 C, Java, Python 등 다양한 프로그래밍 언어에서 사용할 수 있습니다.

C++ STL에서의 다차원 vector

다차원 vector는 각 행이 vector로 간주되는 행 수가 가변적인 다차원 vector입니다. 각 인덱스에는 vector가 저장됩니다. 반복자를 사용하여 접근하거나 순회할 수 있으며,각 vector는 서로 다른 길이를 가질 수 있습니다.

예시 코드: 이중 vector 사용 예

// 다차원 vector 사용 예제
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    // 다차원 vector 선언
    vector<vector<int>> matrix;

    // 다차원 vector에 값 추가
    vector<int> row1 = {1, 2, 3};
    vector<int> row2 = {4, 5, 6};
    vector<int> row3 = {7, 8, 9};
    matrix.push_back(row1);
    matrix.push_back(row2);
    matrix.push_back(row3);

    // 다차원 vector 순회 및 출력
    for (int i = 0; i < matrix.size(); i++)
    {
        for (int j = 0; j < matrix[i].size(); j++)
        {
            cout << matrix[i][j] << " ";
        }
        cout << "\n";
    }

    return 0;
}
output
1 2 3
4 5 6
7 8 9

루프문 안에서의 요소 삭제

벡터를 순차적으로 탐색하여 원하는 인덱스에 erase를 사용할 땐 주의가 필요하다.
이유는 순차적으로 탐색할때 중간에 요소가 삭제되면 총 개수가 줄어들게 됩니다. For루프시 삭제가 일어나면 index를 증가 해서는 안됩니다.
다음 항목에 그 예제가 있습니다.

예시코드: for 문안에서의 vector 삭제

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> vec;
    vector<int>::iterator it;

    vec.push_back(1);
    vec.push_back(2);
    vec.push_back(3);
    vec.push_back(4);
    vec.push_back(5);
    vec.push_back(6);

    cout << "Vector 값 출력 -----------------------" << endl;
    for (int i = 0; i < vec.size(); i++)
        cout << vec[i] << endl;

    for (it = vec.begin(); it != vec.end(); )
    {
        if (*it == 2) // 값이 2일 경우 삭제
        {
            it = vec.erase(it); // index를 증가 시키지 않는다. 
        }
        else
        {
            it++; // index 증가
        }
    }

    cout << "Vector 값 출력 -----------------------" << endl;
    for (int i = 0; i < vec.size(); i++)
        cout << vec[i] << endl;
}
output
Vector 값 출력 ———————–
1
2
3
4
5
6
Vector 값 출력 ———————–
1
3
4
5
6

결론

C++의 vector는 다양한 작업을 수행하는 데 사용되는 강력한 도구입니다. vector는 동적 배열로 요소를 효율적으로 저장하고 조작하는 데 사용됩니다. STL 라이브러리의 일부로 제공되며, 알고리즘, 반복자 및 다른 컨테이너와 함께 사용하여 C++ 프로그래밍을 단순화하는 데 도움이 됩니다. 이 블로그를 통해 vector의 기본 개념과 다양한 함수를 이해하고, C++ 프로그램에서 vector를 활용하는 방법을 배웠습니다. vector는 C++ 개발자에게 권장되는 핵심 데이터 구조 중 하나이며, 다양한 응용 프로그램을 구현하는 데 유용합니다. C++에서 vector를 자유롭게 활용하여 강력한 프로그램을 작성해 보시기 바랍니다.

Leave a Comment