Programmers_정렬_가장 큰 수
조건
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
입출력 예시
-입력: [6,10,2]
-출력: "6210"
-입력: [3,30,34,5,9]
-출력: "9534330"
풀이
첫 번째 도전
function solution(numbers) {
let answer = numbers.sort((a,b) => -a)
.join('');
return answer;
// "9534303"
}
처음엔 sort()를 이용한 간단한 문제라고 생각했으나 1, 10 자리수에 상관없이 앞의 숫자 순서로 정렬하는 방법을 끝내 찾아내지 못하고 계속 이상한 결과만 내보냈다. sort()안에서 콜백으로 a-b 나 b-a 는 자주 사용했지만 도대체 어떻게 해야 34 다음에 3, 그리고 30이 오게 할지 고민하였다. (9534303보다 9534330이 더 크므로...)
레퍼런스 코드
function solution(numbers) {
let answer = numbers.map(c => c + '')
.sort((a,b) => (b + a) - (a + b)).join('');
return answer[0] === '0' ? '0' : answer;
// "9534330"
}
다른 사람들이 작성한 레퍼런스 코드를 보니 일단 map을 이용해 numbers 배열의 요소를 문자열로 바꿔주었다. 그 뒤 sort의 정렬 조건을 (b + a) - (a + b)로 설정해주니 원했던 순서가 되었다.
여기서 sort 알고리즘을 조금 더 살펴보자. 기본적으로 sort() 내부의 함수는 다음과 같이 2개 인자의 연산을 이용하여 값이 양수이면 2개의 인자를 자리바꿈하고, 음수면 바꾸지 않는 방식을 이용한다.
let arr = [2, 3, 1];
arr.sort((a, b) => a - b);
// 2 - 3 = -1 이므로 2와 3은 바꾸지 않음
// 3 - 1 = 2 이므로 3과 1은 자리바꿈
// 2 - 1 = 1 이므로 2와 1 자리바꿈
// [1, 2, 3]
그렇다면 (b + a) - (a + b)는 무슨 의미일까?
let arr = ['3', '30', '34'];
arr.sort((a, b) => (b + a) - (a + b));
// a = 30, b = 3 return 27
// a = 34, b = 30 return -396 ?
// a = 34, b = 3 return -9 ?
// ...
// ['34', '3', '30']
MDN에 따르면 (firstEl, secondEl)로 표기되어 있어서 순서대로 비교하는 것 같지만 실제 vscode에서 디버그를 찍어 본 결과 저렇게 a가 나중에 온 숫자인 것을 확인할 수 있다... 또한 a, b 의 연산 결과가 음수인 경우의 자리 바꿈은 도대체 어떻게 일어난 것일까... 이 글을 통해 a와 b의 순서는 엔진에 따라 중구난방으로 정해진다는 사실을 알게 되었다. 그렇다면 처음 배열을 ['34', '30', '3']과 같이 뒤집은 뒤 양수가 나온 30과 3 끼리만 순서를 바꾸어 준 것일까?
아직 완벽하게 이해가 되지 않는다. 그러나 이번 문제를 통해서 sort()를 깊이있게 공부할 수 있었고, 문자열과 숫자의 정렬순서가 다르다는 점을 알았다. 앞으로 계속 공부하다가 정렬 메소드를 완벽하게 이해하게 되는 순간 다시 돌아와 마무리 지으려 한다.
참고
[javascript] sort 함수의 콜백함수 질문
MDN - Array.prototype.sort()
Author And Source
이 문제에 관하여(Programmers_정렬_가장 큰 수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sy3783/Programmers정렬가장-큰-수저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)