Sungtt

Lev.2 프로그래머스 가장 큰 수 JavaScript, 정렬 본문

코테

Lev.2 프로그래머스 가장 큰 수 JavaScript, 정렬

sungtt 2023. 1. 23. 19:34

0 또는 양의 정수가 담겨있는 배열이 매개변수로 주어진다.

0이 들어간다는건 분명 [0,0,0] 식의 테스트 케이스도 있다는 힌트같다.

이 케이스에 대한 예외처리는 따로 해주고, 일반적인 경우로만 생각해보자.

 

[6,10,2]를 '6210'으로 가공하는 과정을 위 문제 설명에 맞게끔 구현하자.

 

요구하는 리턴을 보면 데이터 타입이 숫자에서 문자열로 바뀌는걸 알 수 있다.

그리고 각 숫자의 합이 필요한 것이 아니기때문에 문자열로 바꿔서 요소를 비교해보자.

    let stringArr = numbers.map(i => i.toString());
    console.log(stringArr) // ['6','10','2']

 

 

이 후 sort를 통해 a와 b를 ba , ab으로 더하여 비교했을 때 값이 더 높아지는 문자열을 앞으로 보내면 된다.

10 + 6 = 106

6 + 10 = 610

return 6

2+10 = 210

10+2 = 102

return 2

    let sortArr = stringArr.sort((a,b) => (b+a) - (a+b));
    console.log(sortArr) // [ '6', '2', '10' ]

 

마지막으로 배열의 요소를 연결해 하나의 문자열로 만들어주는 join()을 사용하면 끝이다.

let resultArr = sortArr.join('')
console.log(resultArr) // "6210"

 

이 후 요소가 0일 경우에 대한 방어코드를 작성하고 마무리하자.

return resultArr[0] === '0' ? '0' : resultArr;

 

 


여기서 sort의 사용방식이 왜 저런것인지 헷갈릴 때가 있다.

정확히 짚고 넘어가자

sort의 콜백함수인 compareFunction을 사용하지않으면 각 요소는 자동으로 문자열로 변환되어

각 문자의 유니코드 코드 포인트 값에 따라 정렬된다.

 

하지만 보시다시피 호출하였고 우리만의 정렬기준을 세운것이다.

 

a,b를 비교했을 때 아래와 같은 리턴값으로 정렬 방법을 선택할 수 있다.

- 0보다 작을 경우 a가 먼저 온다.

- 0보다 큰 경우, b가 먼저 온다.

- 0일 경우 요소를 변경하지않고 다음 요소에 대해 탐색한다.

 

첫번째 정렬 시 a = '6' 와b = '10'을 연결한 106과 610을 뺄셈한다.

문자열이지만 뺄셈을 통해 숫자로 자동 형변환되어 -504라는 값이 나왔고

이는 0보다 작은 경우에 해당한다. 즉 a가 먼저 오게 된다.

그렇게되어 6,10 순을 유지한채 다음 요소를 탐색한다.

 

두번째 정렬 시 a = '10', b = '2'을 연결한  210과 102를 뺄셈한다.

결과는 108이다.

0보다 큰 경우를 따라 b보다 a를 낮은 인덱스로 정렬한다.

그렇게 2,10로 정렬된다.

 

Comments