접하게된 boj 18869번 문제에 대해서, 쭉 나열되어 있는 정보들에 대해서 이걸 어떤식으로 받아들일까 고민을 했는데, 참고 코드를 보니 이걸 2중 배열을 통하여서 정보들을 행당 열별로 쭉 받아들이고 그걸 전체 행에 대해서 받아들이는 방법으로 이걸 2중 배열로 받아들이는 코드를 보게 되었다.
그리고 이 문제의 경우는 좌표압축을 통해서 정보들을 간결하게 만들어서 각각의 좌표압축된 행성에 대한 정보들끼리 비교하는 연산을 수행하는 문제였는데,
이때에 내가 접하게 된 참고 코드에서 사용한 방법을 기록해보면,
void compress(int a[]) {
vector<int> v(a, a + n);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
for (int i = 0; i < n; i++)
a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin();
}
이런식으로 compress 함수를 만들어서 배열을 행별로 받아들이고, 그 행들을 compress 함수로 쭉 좌표압축을 해놓고, 다시 입력받은
배열에 압축된 결과들을 새롭게 넣어줘서 압축된 좌표들을 표시해주는 형태였다.
이때에 지금까지는 함수에 배열을 인자로 받는 형태를 보지 못해서
void compress(int a[]) 형태로 작성하는것도 익숙치 않았고,
vector<int> v(a,a+n); 형태로 작성하는 코드도 어떤 것인지 처음에는 이해가 잘 가지 않았지만,
void compress(int a[])는 배열을 인자로 받는 함수에 대한 선언,
그리고 vector<int> v(a,a+n); 형태의 코드는 배열 a의 인자들을 전체를 다 vector에 v에 복사해 넣는 형태로 보여져서 이에 대해서 검색해보았다.
생각했던 것과 마찬가지로,
void compress(int a[])는 배열을 매개변수로 받는 함수를 선언하는 방식. int a[]는 배열 'a'를 나타내며, 매개변수로 전달된 배열의 크기는 함수 내에서 추론되지 않으므로, 배열의 길이 정보는 따로 전달되어야 한다. -- 는 부분이 있다. 여기서 주의해야 할 부분은 배열의 길이 정보를 따로 전달해주어야 한다는 것인 부분이라고 생각된다.
그래서 함수의 내부에서 vector<int> v.(a,a+n); 형태로 배열의 모든 값들을 복사해서 vector에 복사해 넣을때, 저런식으로 n이라는걸 통해서 배열의 길이 정보가 전달되어야지 가능한 연산일 것으로 보여진다.
그리고 vector<int> v(a,a+n);는 반복자를 이용해서 배열의 원소들을 벡터에 값을 모두 복사해 넣는 연산이고, 이 연산은 c++11 부터 가능한 기능이다. 아마 이렇게 표현하지 않아도, 개별 배열의 원소들을 for문으로 push_back(a[i]) 형태로 넣는것이 그동안 내가 자주 보게된 형태의 코드였던것 같은데, 이런식으로 전체를 한번에 벡터를 선언할때 복사해서 넣어줄 수 있다는걸 알면 조금 더 코드를 간결하게 표현할 수 있을것 같다.
배열을 원소로 받는 함수의 선언,
그리고 백터를 처음 선언할때 배열의 원소들을 원하는 영역만큼 복사해서 바로 할당해서 넣어줄 수 있는
표현 방법 (vector<int> v(a,a+n); 에 대해서 배웠는데, 이것들을 잘 활용해서 앞으로 코드를 작성할때 활용해보도록 하자.
물론 내가 알고있는 방법으로, 함수로 선언하지 않고 그대로 코드로 작성해서, for문을 통해서 배열의 원소들을 차례로 push_back(a[i])형태로 작성해도 같은 결과를 얻을 수 있다.
둘다 익숙하게 사용할 수 있도록 익히도록 하자.
++++++++++
추가적으로 함수의 매개변수로 배열을 전달해 줄때에 대해서 검색해보았다.
확실하게 배열의 크기 정보는 따로 전달해주어야 함수 내에서 올바르게 처리할 수 있다고 한다.
이때에 내가 접한 참고 코드의 경우는 간결하게 일관되게 정해져있는 n이라는 값을 처음 입력으로 받기 때문에 함수 내부에 바로 n에 대한 값을 통해서 사이즈 값을 사용하는 형태로 사이즈 크기를 매개변수로 전달해주지 않고 내부적으로 그대로 그 값을 사용했다.
이렇게 코딩테스트 용으로 작성할때는 이런식으로 작성해도 충분할것 같다.
가장 중요한건 사이즈 값을 따로 전달해주어야 한다는 점이라고 생각된다. 그 점을 확실하게 기억하고 잘 활용하도록 하자.
+++++++++++++++++++++++++
for(int i=0; i<m; i++){
compress(arr[i]);
}
이렇게 되어있을때,
그리고
for(int i=0; i<m-1;i++){
for(int j=i+1;j<m;j++){
cnt+=compare(arr[i],arr[j]);
}
}
이렇게 되어있을때,
내가 작성한 compare 함수와 compress 함수를 보면,
void compress(int a[]){
vector<int> v(a,a+n);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(int i=0; i<n; i++)
a[i]=lower_bound(v.begin(),v.end(),a[i])-v.end();
}
bool compare(int a[],int b[]){/*이게 a[]와 b[]가, 입력으로 arr[i],arr[j]가 주어졌을때,
행에 대한 연산이 아니라 열에 대한 연산을 한다는것을 주의해야 한다.*/
for(int i=0; i<n;i++){
if(a[i]!=b[i]) return false;
}
return true;
}
이런 형태인데, compare 함수의 오른쪽 편에 주석으로 달아놓은 것처럼, 함수 내부에서의 동작은 마치 잘못 착각하면
행에 대해서의 연산처럼 보여질 수 있는데, 열에 대한 결과물들에 대해서 나오게 된다.
행은 이미 for문 내부에서 행이 정해지고, 그 행에 해당하는 배열들에 대해서 compare 함수와 compress 함수가 열들에 대해서
순차적으로 연산이 수행된다.
예를들면 각각의 함수들에 들어가는 값은 arr[4][] 형태로 들어가는 것처럼 인식해야 한다. 그렇게 되어있는 형태로 행은 정해진 값들을
인자로 받고, 열로 이루어진 배열의 원소들에 대해서 수행된다. 헷갈리지 않도록 주의하자.
'알고리즘 > BOJ' 카테고리의 다른 글
boj 2473번 문제를 통해 배우게된 정말정말 중요하고 헷갈리기 쉬운 int overflow에 관하여. (0) | 2023.06.10 |
---|---|
boj 2467번 문제에 대한 이분탐색과 투 포인터 를 이용한 풀이에 대한 시간 복잡도의 차이점에 대하여. (0) | 2023.06.10 |
boj 16401번 문제를 풀며 접하게된 *max_element(l,l+n);의 활용. (0) | 2023.06.09 |
boj 1654 랜선 자르기 문제를 (st+en)/2 형태로 작성할 수 있는 방법에 대한 참고 블로그. (0) | 2023.06.09 |
2^31-1을 표현하는 16진수 표현법. (0) | 2023.06.08 |