c++에서 vector는 ps를 할 때 상당히 많이 쓰는 자료구조입니다. 현업에서는 얼마나 많이 쓸 지 모르겠습니다만, 몰라서 손해를 볼 구조는 아닌 듯 싶습니다. 한 번에 너무 많이 쓰면 내용이 길어질 듯 싶으니, 3편에서 4편에 걸쳐서 쓰도록 하겠습니다. 오늘은, 2차원으로 선언된 2차원 vector를 어떻게 사용해야 하느냐입니다.

 

 보통, 리턴 값이나 파라미터가 강제가 되는 코딩 테스트의 경우, vector <vector<int>>만 나와도 당황할 수 있어요. 오늘은 이것을 어떻게 읽어내고, 만약에 이 2차원 벡터를 리턴해야 할 일이 있을 때 어떻게 해야 되는지만 보도록 하겠습니다.

 

 


 먼저 읽어내는 것은 그리 어렵지 않습니다. 어짜피 vector의 vector라고 하면, 동적 배열을 담고 있는 동적 배열이기 때문이에요. 이것을 그림으로 단순하게 도식화 시켜 보겠습니다.

 

 

 그러면, 실제 배열이 있고, size와 capacity와 같은 인자들이 있습니다. 여기서, 노란색 부분은 이미 원소가 들어가 있는 것이고, 보라색은 공간만 있지, 아직 값이 들어가지 않았습니다. 이 배열의 원소가 int다. 그러면 int형을 저장할 겁니다. char면? char형을. int형 벡터면 int형 벡터를 저장할 거에요. 그러면 vector <vector <int>> v는 무엇을 의미하나요? 동적 배열을 저장하는 동적 배열 정도라고 생각하면 편하겠습니다. 만약에 원소가 Dynamic array라고 한다면..

 

 

실제로 요런 식으로 저장이 될 거에요. 이제 아래 코드를 봅시다.

 

 

 2차원 동적 배열이 들어왔습니다. 어떻게 읽어내면 될까요? 일단, tar의 size를 구하기 위해서 tar.size()를 호출하면 됩니다. 20번째 줄의 for loop를 유심히 보셔도 좋을 듯 싶습니다. 다음에, tar[i] 또한, Dynamic array입니다. 그러면, tar[i].size()를 알아낸 다음에 그것 만큼 순회하면 될 거에요. 22 ~ 23번째 줄이 그러한 일을 수행합니다. 읽어 내는 것은 어렵지 않아요.

 

 


 그러면 리턴해야 될 일이 있을 때에는 어떻게 해야 할까요? 특정한 값으로 초기화를 하지 않는다면, 처음에 2차원 벡터 res을 지역 변수로 물려놓았다면, 아래와 같이 메모리에 들어갈 겁니다.

 

 여기서, [0]번째 원소는 ?입니다. 그러면, res의 0번째 원소에 접근이 가능할까요? 글쎄요. 이건 잘 모르겠습니다. 그런데

 

 

 이 경우에는 힘듭니다. res에 원소가 하나도 들어가지 않았기 때문입니다.

 

 

 즉, 그림에서 con의 0번째 원소, 즉 arr[0]이 어디를 가리키고 있는지 모르고 있는 상황입니다. 그 상황에서, size라던지 capacity와 같은 필드에 접근하려고 한다면, 프로그램이 이상하게 동작할 거에요.

 

 

 그렇다면 어떻게 해야 할까요? push_back 등으로 벡터를 넣으면 됩니다.

 

 

 int를 저장하는 동적 배열을 넣었습니다. 이 상태에서는 con[9].size() 등의 연산을 할 수 있습니다. con[0]에 int를 저장하는 동적 배열이 들어있기 때문입니다. 그러면 con[0].push_back(1); 이렇게 해도 되겠군요. 네.

 

 

 con[0]에 벡터가 들어갔기 때문에, con[0].push_back(1); 또한 vaild한 operation입니다. 이 문장을 수행하고 나면 다음 그림과 같이 메모리가 할당이 됩니다. 큰 그림을 이렇게 그리시면 됩니다.

 

 


 이제, r행 c열의 2차원 vector를 생성해 보겠습니다. r = 10, c = 5라고 합시다.

 

 

 생성자의 1번째 인자에 size, 2번째 인자에 초기화할 값을 넣어줄 수 있어요. vector <int> (5,0)은, 크기가 5이고, 0으로 모두 초기화를 한 동적 배열을 생성하겠다는 의미에요. 저는, 14번째 줄에서, res에 크기가 5이고 모두 0으로 초기화한 벡터를 계속 넣고 있습니다. 그러면 열의 크기가 모두 다르다면 어떻게 해야 하나요?

 

 

 간단합니다. default 생성자로 벡터를 생성한 다음에 그것을 res에 넣습니다. 14번째 줄에. 그러면 res[i]는, int 자료형을 저장하는 동적 배열입니다. 여기에, 넣고 싶은 만큼 push_back을 호출해 주면 됩니다. 위 예제에서는, res[i]에는 i+1개의 원소를 넣습니다.

 

 

 이 정도만 이해하셔도 매개변수나 리턴형이 강제되는 코딩테스트에서, 2차원 벡터 때문에 문제가 생기는 경우가 없을 듯 싶습니다.