최근에 머리도 식힐 겸 백준에서 쉬운 문제들 풀면서 랭킹을 올리고 있어서 포스트가 자주 있지는 못했는데 간단한 내용으로 C++에서 2차원 가변 크기 배열(벡터) 선언하는 법을 정리하고 가려고 합니다.
2차원 벡터를 정확히 N*N 크기만큼만 배열을 할당하고 이를 사용하기 위해서는 다음과 같이 코드를 작성해주면 됩니다.
N*N 크기의 배열을 입력받고 그대로 출력하는 코드입니다.
#include <bits/stdc++.h>
#define int long long
using namespace std;
main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
int N; cin >> N;
vector<vector<int>> v(N, vector<int>(N));
for(int i=0; i<N; i++)
for(int j=0; j<N; j++) cin >> v[i][j];
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) cout << v[i][j] << " ";
cout << "\n";
}
}
vector<vector<int>> v(N, vector<int>(N));과 같이 선언해주면 됩니다.
프로그램을 돌려보면 위와 같이 정상적으로 작동하는 것을 확인할 수 있습니다.
마찬가지로 N*N 크기의 배열이 아닌 N행 M열 크기의 배열을 선언하기 위해서는 다음과 같이 코드를 작성해주면 됩니다.
#include <bits/stdc++.h>
#define int long long
using namespace std;
main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
int N, M; cin >> N >> M;
vector<vector<int>> v(N, vector<int>(M));
for(int i=0; i<N; i++)
for(int j=0; j<M; j++) cin >> v[i][j];
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) cout << v[i][j] << " ";
cout << "\n";
}
}
vector<vector<int>> v(N, vector<int>(M));과 같이 선언해주면 됩니다.
N개짜리의 벡터 각각이 M개의 크기를 가지고 있다는 뜻입니다.
즉, N*M 크기의 공간이 할당된 것입니다.
여기에 조금 더 심화시켜서 할당 공간의 값들을 특정 값으로 초기화시킬 수도 있습니다.
예를 들어 다음과 같이 코드를 작성하면, N*M 크기의 배열에 각각의 칸에 -1의 값을 저장할 수 있습니다.
이는 최단 경로 알고리즘과 같이 초깃값을 특정 값으로 채워야 할 때 용이할 수 있습니다.
#include <bits/stdc++.h>
#define int long long
using namespace std;
main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
int N, M; cin >> N >> M;
vector<vector<int>> v(N, vector<int>(M, -1));
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) cout << v[i][j] << " ";
cout << "\n";
}
}
vector<int>(M, -1)과 같이 M 옆에 어떤 값으로 초기화할지만 지정해주면 됩니다.
위와 같이 초기화가 제대로 이루어졌음을 확인할 수 있습니다.
다음과 같이 이미 선언된 2차원 벡터를 resize 함수를 통해 크기를 재할당 시켜줄 수도 있습니다.
#include <bits/stdc++.h>
#define int long long
using namespace std;
main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
vector<vector<int>> v;
int N, M; cin >> N >> M;
v.resize(N, vector<int>(M));
for(int i=0; i<N; i++)
for(int j=0; j<M; j++) cin >> v[i][j];
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) cout << v[i][j] << " ";
cout << "\n";
}
}
v.resize(N, vector<int>(M))과 같이 코드를 작성해주면 이미 저장되어있던 벡터의 크기가 N*M의 크기로 재할당됩니다.
위와 같이 코드가 정상 작동함을 알 수 있습니다.
+ 여기에 v.resize(N, vector<int>(M, -1))과 같이 하여 resize와 값의 초기화를 동시에 수행해줄 수도 있습니다.
언제 사용되는가?
다만 우리는 일반적으로 문제를 풀 때 int arr[MAX][MAX];와 같이 선언을 해서 사용하기 때문에 굳이 벡터를 사용해야 할 필요성을 느끼지 못하긴 합니다.
가변 벡터로 선언해야만 풀리는 경우는 아주 드물지만, 아무튼 메모리를 효과적으로 사용할 수 있다는 점에서 장점이 있습니다.
vertex와 edge가 아주 많은 그래프 문제를 풀 때 가끔 2차원 고정 크기 배열을 사용하면 메모리 초과나 각종 문제가 발생할 수 있습니다.
여러 개의 테스트 케이스를 사용해야 하는 while(T--) { (코드) }와 같은 구조로 문제를 풀 때도 가변 크기 벡터 선언이 유용할 수 있습니다.
'알고리즘 > 알고리즘 공부 내용 정리' 카테고리의 다른 글
C++ 제곱근 분할법 알고리즘 (Sqaure-root Decomposition, 예제 풀이 포함) (0) | 2022.06.11 |
---|---|
C++ 스위핑 알고리즘 (C++ Sweeping, BOJ 2170, BOJ 15922) (0) | 2022.06.06 |
큰 수 덧셈/더하기 알고리즘 구현 (C++) (백준 BOJ 15353 : 큰 수 A+B) (0) | 2022.04.07 |
밋 인더 미들 (Meet in the middle, 중간에서 만나기) 알고리즘 (백준 BOJ 1450) (1) | 2022.04.07 |
투 포인터 알고리즘 (백준 BOJ 2470 / Codeforces 1656B) (0) | 2022.04.06 |