알고리즘/알고리즘 공부 내용 정리

C++ 2차원 벡터 (가변 크기 배열) 선언하는 법 (+ resize로 크기 재할당)

restudy 2022. 5. 22. 19:29
반응형

최근에 머리도 식힐 겸 백준에서 쉬운 문제들 풀면서 랭킹을 올리고 있어서 포스트가 자주 있지는 못했는데 간단한 내용으로 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--) { (코드) }와 같은 구조로 문제를 풀 때도 가변 크기 벡터 선언이 유용할 수 있습니다.

 

 

 

반응형