
안녕하세요, 오늘은 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차원 동적 배열 선언 |
#include <vector>
using namespace std;
vector<int> v; // 자동으로 크기 조절 가능
| 비교 항목 | 배열 (int arr[100]) | 벡터 (vector<int> v) |
|---|---|---|
| 크기 변경 | ❌ 고정 크기 | ✅ 동적 크기 조절 가능 |
| 안전성 | ❌ 오버플로우 위험 | ✅ 범위 체크 가능 (with .at()) |
| 삽입/삭제 | ❌ 어려움 | ✅ 매우 쉬움 (push_back, erase 등) |
| STL 연동 | ❌ 불편 | ✅ 다양한 STL 알고리즘 사용 가능 |
벡터는 정수형 배열처럼 사용하면서도 동적으로 크기를 조절할 수 있는 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
벡터는 배열과 달리 값을 쉽게 뒤에 추가하거나 제거 가능
또한 중간 삽입/삭제도 매우 유연하게 처리
| 함수 | 설명 | 사용 예시 |
|---|---|---|
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
벡터는 배열처럼 인덱스로 값을 접근할 수 있지만, 보다 안전한 접근 방법도 제공
| 접근 방식 | 설명 | 특징 |
|---|---|---|
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()은 예외가 발생할 수 있으므로, 안정성이 필요한 경우 추천!
vector<int> v = {1, 2, 3};
// 인덱스 기반
for (int i = 0; i < v.size(); i++) {
cout << v[i];
}
// 범위 기반
for (int x : v) {
cout << x;
}
| 함수 | 설명 |
|---|---|
size() | 원소 개수 반환 |
empty() | 비어있는지 확인 (true/false) |
resize(n) | 크기 조정 |
capacity() | 실제 할당된 메모리 공간 |
<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()는 마지막 다음 요소▶ 내림차순 정렬
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}
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열, 값은 0 | 2차원 배열처럼 사용 |
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 호환성이 뛰어난 자료구조push_back, erase, sort, at 등은 코딩 테스트 필수 함수