[C++] 동적 배열 vector 가이드

Ma_Seokjae·2025년 4월 21일
post-thumbnail

안녕하세요, 오늘은 C++에서 많이 사용하는 vector에 대해서 정리해보려고 합니다. 사실은 제가 코딩 테스트를 볼 때 많이 사용하면서도,,
가끔 막연히 생각이 안나는 경우가 종종 있어서,,,ㅎ 정리를 시작했습니다. 같이 보시면서, 언제든 편안하게 사용할 수 있도록 해봅시다 :)


🗂️ 요약: vector 핵심 기능 정리

기능 구분문법설명
선언vector<int> v;정수형 벡터 선언
초기화vector<int> v(5, 10);크기 5, 모든 값 10
삽입v.push_back(x);뒤에 요소 추가
삭제v.pop_back();마지막 요소 삭제
접근v[i], v.at(i)at()은 예외 처리 포함
정렬sort(v.begin(), v.end());오름차순 정렬
이중 벡터vector<vector<int>> v(n, vector<int>(m));2차원 동적 배열 선언

📘 vector란?

  • 동적 배열을 제공하는 STL 컨테이너
  • 배열과 유사하지만 크기 조절, 메모리 관리, STL 연동 등에서 압도적인 이점을 가짐
#include <vector>
using namespace std;
vector<int> v;  // 자동으로 크기 조절 가능

⁇ 왜 vector를 쓰는가? (vs 배열)

비교 항목배열 (int arr[100])벡터 (vector<int> v)
크기 변경❌ 고정 크기✅ 동적 크기 조절 가능
안전성❌ 오버플로우 위험✅ 범위 체크 가능 (with .at())
삽입/삭제❌ 어려움✅ 매우 쉬움 (push_back, erase 등)
STL 연동❌ 불편✅ 다양한 STL 알고리즘 사용 가능

🛠️ 주요 기능 상세 정리

🔹 1. 벡터 선언과 초기화

벡터는 정수형 배열처럼 사용하면서도 동적으로 크기를 조절할 수 있는 STL 컨테이너

코드설명
vector<int> v1;아무 값도 없는 빈 벡터 선언
vector<int> v2(5);크기 5, 값은 전부 0 (기본 초기값)
vector<int> v3(5, 100);크기 5, 값은 전부 100
vector<int> v4 = {1, 2, 3, 4, 5};초기화 리스트로 선언과 동시에 값 설정

🧑🏻‍💻 실습 예제

vector<int> v4 = {1, 2, 3, 4, 5};

for (int x : v4) {
    cout << x << " ";
}
// 출력: 1 2 3 4 5

🔹 2. 값 삽입과 삭제

벡터는 배열과 달리 값을 쉽게 뒤에 추가하거나 제거 가능

또한 중간 삽입/삭제도 매우 유연하게 처리

함수설명사용 예시
push_back(x)맨 뒤에 값 x 추가v.push_back(10);
pop_back()맨 뒤 값 제거v.pop_back();
insert(it, x)it 위치에 x 삽입v.insert(v.begin() + 1, 20);
erase(it)it 위치의 값 삭제v.erase(v.begin());
clear()모든 요소 삭제v.clear(); (크기 0이 됨)

🧑🏻‍💻 실습 예제

vector<int> v = {1, 2, 3};

v.push_back(4);            // [1, 2, 3, 4]
v.erase(v.begin() + 1);    // [1, 3, 4]
v.pop_back();              // [1, 3]

각 단계별로 출력하면:

for (int x : v) cout << x << " ";  // 출력: 1 3

🔹 3. 원소 접근

벡터는 배열처럼 인덱스로 값을 접근할 수 있지만, 보다 안전한 접근 방법도 제공

접근 방식설명특징
v[i]인덱스 접근가장 빠름. 범위 오류 발생해도 예외 발생 없음
v.at(i)인덱스 접근예외 안전. 범위 벗어나면 out_of_range 예외 발생
v.front()첫 번째 원소 반환v[0]과 동일
v.back()마지막 원소 반환v[v.size() - 1]과 동일

🧑🏻‍💻 실습 예제

vector<int> v = {1, 2, 3};

cout << v.front() << endl;   // 1
cout << v.back() << endl;    // 3
cout << v.at(0) << endl;     // 1

⚠️ v.at()은 예외가 발생할 수 있으므로, 안정성이 필요한 경우 추천!


🔹 4. 반복과 출력

vector<int> v = {1, 2, 3};

// 인덱스 기반
for (int i = 0; i < v.size(); i++) {
    cout << v[i];
}

// 범위 기반
for (int x : v) {
    cout << x;
}

🔹 5. 크기와 상태 확인

함수설명
size()원소 개수 반환
empty()비어있는지 확인 (true/false)
resize(n)크기 조정
capacity()실제 할당된 메모리 공간

🔹 6. 정렬 및 기타 STL 연동 (with <algorithm> 헤더)

📌 STL에서 벡터와 자주 사용하는 함수 요약

함수설명예시
sort(begin, end)오름차순 정렬sort(v.begin(), v.end());
sort(rbegin, rend)내림차순 정렬sort(v.rbegin(), v.rend());
reverse(begin, end)순서 뒤집기reverse(v.begin(), v.end());
find(begin, end, val)특정 값 찾기find(v.begin(), v.end(), 3);
unique(begin, end)중복 제거 (정렬 필요)unique(v.begin(), v.end());
count(begin, end, val)특정 값 개수 세기count(v.begin(), v.end(), 2);
min_element(begin, end)최솟값 반복자 반환*min_element(...)
max_element(begin, end)최댓값 반복자 반환*max_element(...)

sort(): 정렬

▶ 오름차순 정렬 (기본)

#include <algorithm>
vector<int> v = {3, 1, 4, 2};
sort(v.begin(), v.end());  // 결과: {1, 2, 3, 4}
  • begin()은 첫 요소를 가리키는 반복자, end()는 마지막 다음 요소
  • 내부적으로 QuickSort/IntroSort 기반으로 매우 빠름

▶ 내림차순 정렬

sort(v.rbegin(), v.rend());  // 결과: {4, 3, 2, 1}
  • rbegin()은 뒤에서부터 시작하는 역방향 반복자
  • sort(rbegin, rend) 구조로 바로 내림차순 정렬 가능

▶ 사용자 정의 정렬 (예: 홀수 먼저, 그다음 짝수)

sort(v.begin(), v.end(), [](int a, int b) {
    return a % 2 > b % 2;
});

reverse(): 순서 뒤집기

reverse(v.begin(), v.end());  // {4, 3, 2, 1} → {1, 2, 3, 4}
  • 정렬과 다르게, 단순히 순서를 역순으로 뒤집는 함수
  • O(n) 시간 복잡도

find(): 특정 값 찾기

auto it = find(v.begin(), v.end(), 3);
if (it != v.end()) {
    int index = it - v.begin();  // 위치 출력
    cout << "3의 위치: " << index;
}
  • 값이 없으면 v.end() 반환

unique(): 중복 제거 (정렬 후 사용)

sort(v.begin(), v.end());                 // 먼저 정렬
auto it = unique(v.begin(), v.end());    // 중복 제거
v.erase(it, v.end());                    // 중복된 뒷부분 삭제
  • unique()중복 요소를 뒤로 밀고 반복자 반환만 해줌
  • 진짜로 삭제하려면 erase() 필요

count(): 특정 값 개수 세기

int cnt = count(v.begin(), v.end(), 2);  // 2가 몇 개인지 반환

min_element / max_element

int mn = *min_element(v.begin(), v.end());
int mx = *max_element(v.begin(), v.end());
  • 반복자를 반환하므로 로 값을 추출해야 함

🔁 이중 벡터 (vector<vector<int>>)

🧩 이중 벡터 선언 방식 요약표

선언 방식의미활용 예
vector<vector<int>> v1;선언만나중에 push_back, resize, 대입 등으로 할당
vector<vector<int>> v2(n);n개의 빈 행 생성v2[0].push_back(x)처럼 사용 가능
vector<vector<int>> v3(n, vector<int>(m));n행 m열, 값은 02차원 배열처럼 사용
vector<vector<int>> v4(n, vector<int>(m, val));n행 m열, 모든 값 val전부 초기값 지정

1. 선언만 하고 나중에 할당 (v1 방식)

vector<vector<int>> v1;  // 빈 2차원 벡터

= 연산자 사용해 한 번에 할당

v1 = vector<vector<int>>(3, vector<int>(4, 1));
// 3행 4열, 모든 값 1

push_back()으로 한 줄씩 추가

for (int i = 0; i < 3; i++) {
    vector<int> row = {i, i+1, i+2};
    v1.push_back(row);
}
// 결과: [[0,1,2], [1,2,3], [2,3,4]]

resize() 후 직접 접근

v1.resize(3);  // 3행 확보
for (int i = 0; i < 3; i++) {
    v1[i].resize(4);  // 각 행에 4열 추가
    for (int j = 0; j < 4; j++) {
        v1[i][j] = i * j;
    }
}

2. 행만 정해놓고 열은 나중에 (v2 방식)

vector<vector<int>> v2(3);  // 3개의 빈 벡터 (행만 생성됨)

v2[0].push_back(10);
v2[1].push_back(20);
v2[2].push_back(30);

이 방법은 행 수는 고정되어 있고, 각 행마다 열의 수가 다를 수도 있을 때 사용

3. 행과 열 모두 고정 (v3, v4 방식)

vector<vector<int>> v3(3, vector<int>(4));
// 3x4, 기본값 0

vector<vector<int>> v4(2, vector<int>(3, -1));
// 2x3, 모든 값 -1

이 방식은 정해진 크기의 2차원 배열을 한 번에 만들고 싶을 때 유용

🖨️ 출력 예시

for (int i = 0; i < v1.size(); i++) {
    for (int j = 0; j < v1[i].size(); j++) {
        cout << v1[i][j] << ' ';
    }
    cout << endl;
}

📌 이중 벡터 요약

목적추천 선언 방법
나중에 동적으로 만들고 싶을 때vector<vector<int>> v; + push_back, resize
정해진 크기/값으로 한 번에 만들고 싶을 때vector<vector<int>>(n, vector<int>(m, val))
각 행마다 크기가 다른 2차원 구조vector<vector<int>> v(n);v[i].push_back()

✅ 마무리 요약

  • vector동적 크기, 범용성, STL 호환성이 뛰어난 자료구조
  • 이중 벡터는 2차원 배열처럼 사용할 수 있으며, 매우 유연함
  • push_back, erase, sort, at 등은 코딩 테스트 필수 함수
profile
Why not change the code?

0개의 댓글