1. std::vector
1. 2차원 벡터 선언방식
vector<vector<int>> vec;
vector<vector<int>> vec(10);
vector<int> vec[10];
- 첫번째 방식
- 첫번째 방식은 가장 기본적인 방식으로 push_back() 연산을 통해서만 가능
- 처음에 빈 vector에 값을 대입하는 경우에 [ ] 연산자를 통해 대입이 불가능하다. (vector out of range)
- 예시 코드
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> vec;
vector<int> temp1 = { 1,2,3,4,5,6,7,8,9,10 };
vector<int> temp2 = { 1,1,1,1,1,1,1,1,1,1 };
//vec[0] = temp1; 불가능
vec.push_back(temp1);
vec.push_back(temp1);
vec.push_back(temp1);
vec.push_back(temp1);
cout << vec[0][2] << "\n";
vec[2] = temp2;
for (auto v : vec)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
}
실행 결과
- 두번째 방식
- ( ) 안에 숫자만큼 행을 차지하고 시작하는 방식이다. (10개의 빈 행을 가진 2차원 벡터 생성)
- 그렇기 때문에 [ ] 연산자를 통한 접근이 ( ) 안에 숫자만큼 가능해진다.
- 또한 크기를 선언한 이후 push_back 연산도 가능한데, 이는 ( ) 안에 숫자만큼 차지한 공간 이후로 push_back 된다. (동적으로 추가 가능)
- 예시 코드
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> vec(10);
vector<int> temp1 = { 1,2,3,4,5,6,7,8,9,10 };
vector<int> temp2 = { 1,1,1,1,1,1,1,1,1,1 };
vec[0] = temp1; //가능!
//vec[1][2] = 10; 이건 불가능!
vec.push_back(temp1);
vec.push_back(temp1);
vec.push_back(temp1);
vec.push_back(temp1);
cout << vec[0][2] << "\n"; // vec[0] = temp를 해줘서 가능
vec[2] = temp2;
for (auto v : vec)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
}
실행 결과
- 세번째 방식
- 사실 이 방식은 vector<int> 를 10개 나열해 둔 것이다.
- 각각의 행을 vector관련 함수로 다룰 수 있으며, 2차원 배열처럼 사용할 수 있다는 장점이 있다.
- 두번째와 마찬가지로 [ ] 연산자로 각 행에 접근이 가능하다는 장점이 있다.
- 예시 코드
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec[10];
vector<int> temp1 = { 1,2,3,4,5,6,7,8,9,10 };
vector<int> temp2 = { 1,1,1,1,1,1,1,1,1,1 };
vec[0] = temp1; //가능!
//vec[1][2] = 10; 불가능!
cout << vec[0][2] << "\n"; //vec[0] = temp1 해서 가능
vec[2].push_back(1);
vec[2].push_back(2);
vec[2].push_back(3);
vec[2].push_back(4);
vec[2].push_back(5);
vec[2].push_back(6);
vec[2].push_back(7);
vec[2].push_back(8);
vec[2].push_back(9);
vec[2].push_back(10);
vec[2] = temp2;
vec[9] = temp1;
//vec[10] = temp1; 행의 크기 10넘어서서 불가능!
for (auto v : vec)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
}
실행 결과
2. 2차원 배열의 정렬
#include <algorithm> //sort 쓰기 위해서
bool cmp(const vector<int>& v1, const vector<int>& v2)
{
return v1.size() < v2.size();
}
int main()
{
...
vector<vector<string>> vec;
sort(vec.begin(); vec.end(), cmp);
...
}
- 기본적으로 sort를 하면, 각 벡터를 사전순으로 나열해준다.
- 내가 만약 각 행들의 크기순으로 정렬하고 싶다면, 정렬 방식을 새롭게 정의해주면 된다.
- 주의할 점은 세번째 방식으로 선언한 경우 sort의 시작과 끝을 배열처럼 지정해주어야 한다.(아래코드 참고)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(const vector<int>& v1, const vector<int>& v2)
{
return v1.size() < v2.size();
}
int main()
{
vector<int> vec[10];
vector<vector<int>> vec2;
vector<int> temp1 = { 3,4,1,5,6 };
vector<int> temp2 = { 1,1, 1 };
vector<int> temp3 = { 1,2 };
vector<int> temp4 = { 9 };
vec[0] = temp1;
vec[1] = temp2;
vec[2] = temp3;
vec[3] = temp1;
vec[4] = temp4;
vec2.push_back(temp1);
vec2.push_back(temp2);
vec2.push_back(temp3);
vec2.push_back(temp1);
vec2.push_back(temp4);
sort(vec, vec + 5, cmp);
sort(vec2.begin(), vec2.end());
cout << "세번째 방식 sort\n";
for (auto v : vec)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
cout << "---------------\n";
cout << "첫번째 방식 기본 sort\n";
for (auto v : vec2)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
cout << "첫번째 방식 custom sort\n";
sort(vec2.begin(), vec2.end(), cmp);
for (auto v : vec2)
{
for (auto vi : v)
{
cout << vi << " ";
}
cout << "\n";
}
}
실행결과
3. 그렇다면..
- 대부분의 경우 코딩테스트에서 크기가 배열 선언 범위 안에 들어오면, int board[105][105]; 이런식으로 선언하는게 가장 좋았던 것 같다.
- 2차원 배열의 경우 10^5 넘어가면 배열이 너무 커서 불가능함 (배열의 전체 크기는 0x7fffffff를 초과할 수 없다)
- 그래서 만약 범위 크기만큼 선언이 불가능 할때 vector를 사용했던 것 같다.
- 문제를 풀다보면, vec[0] = temp1; 이런식의 접근을 하고 싶을 때가 있어서 세번째 방식을 많이 썼던 것 같다.
- 각각의 방식을 기억에서 문제에 어울리는 방식을 쓰자