* 프로그래머스 > 코딩테스트연습 > 정렬 > 가장 큰 수
문제설명
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.
제한사항
- numbers의 길이는 1 이상 100,000 이하입니다.
- numbers의 원소는 0 이상 1,000 이하입니다.
- 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.
입출력 예
numbers = [6, 10, 2]
return = "6210"
numbers = [3, 30, 34, 5, 9]
return "9534330"
Step 1. 생각해보기
어떻게하면 쉽게 풀수 있을까 어떤 규칙이 있을까 등을 한번 생각해봤는데
제일 왼쪽에 있는 앞에있는 자릿수에 따라 숫자가 나오는것같습니다.
첫번째 [6, 10, 2]
비교를위해 한자리 숫자에만 뒤에 0을 붙여서 만들어보면
[60, 10, 20]
정렬하면
[60, 20, 10]
붙였던 0을 빼면
[6, 2, 10]
이걸 하나로 합치면
"6210"
설명은 생략하고 두번째 예제도 한번 해봅니다.
두번째 [3, 30, 34, 5, 9]
[30, 30, 34, 50, 90]
[90, 50, 34, 30, 30]
[9, 5, 34, 3, 30]
"9534330"
Step 2. 코드로 짜기
- sort() 함수로 정렬을 할건데 어떻게 할건지 내부에 함수로 정의합니다.
- 자릿수가 1자리인것만 0을 붙여서 비교를 하기위해 3항연산자를 만들고
- 2자릿수 이하면 0을붙이고 아니면 그냥 출력한 후에
- 큰수부터 정렬하기위해 j - i 를 해줍니다.
- 마지막으로 정렬된 배열을 문자형으로 바꾸고 reduce 로 문자화된 배열을 하나의 값으로 합쳐줍니다.
Step 3. 테스트
실행 테스트는 통과하였습니다.
정확성 테스트....심각하네요 겨우 3개 통과했습니다.
Step 4. Why?
1. 2자릿수비교만 생각함
제한사항중에 numbers 의 원소는 0~1,000 까지 라고 되어있습니다.
즉 두자릿수 이상의 숫자도 얼마든지 들어올 수 있고 그 부분의 테스트가 실패했을거라 생각합니다.
2. 예외
만약 주어진 numbers 가 [0, 0, 0, 0] 이라면? 그냥 0이 나오면 됩니다.
그러나 숫자로 바꿔주었기 때문에 0000 이 나와버립니다. 이 부분도 문제가 될 수 있다고 하네요
3. 특이한 경우?
그럼 그냥 가장 많은 자릿수를 가진 숫자만큼 다른숫자들을 0을 붙여서 비교해서 출력하면 되지않을까 싶었는데 [12, 121] 같은경우 "12121" 이 가장 큰수 입니다. 하지만 제가 하는 방식대로 진행해버리면
[120, 121] => [121, 120] => [121, 12] => "12112"
가 나와버린다는거죠
자릿수 숫자만 맞춰서 비교해주면 될거라 생각했는데 생각해야 할 부분이 많습니다.
Step 5. 그렇다면 어떻게?
다른분의 예시로 힌트를 좀 받았는데
해당숫자를 반복하는데 4자릿수에서 딱 자르고 비교를하고 [0, 0, 0, 0] 이렇게 0만 나오는 경우는 예외처리로 넘겨주면 될것같습니다.
그렇게하면 위의 [12,121] 도 다른 값들도 적용이 가능합니다.
[12, 121] => [1212, 1211(21)] => [12, 121] => "12121"
* (잘린숫자)
나머지도 한번 해보겠습니다.
[6, 10, 2] => [6666, 1010, 2222] => [6666, 2222, 1010] => [6, 2, 10] => "6210"
[3, 30, 34, 5, 9] => [3333, 3030, 3434, 5555, 9999] =>
[9999, 5555, 3434, 3333, 3030] => [9, 5, 34, 3, 30] => "9534330"
일단 가능한것같습니다. 혹시 또 다른 상황이 예외에 대해 제시할 부분이 있다면 댓글로 달아주시면 감사하겠습니다.
Step 6. 리팩토링
- if 문으로 배열을 돌면서 만약 모두 값이 0이라면 "0" 을 리턴합니다.
- 변수 x 에는 j - i 의 역순의 배열을 넣을겁니다.
- repeat() 메소드는 문자만 가능합니다. 따라서 sting 으로 변경된 숫자를 4번 반복합니다.
- 자릿수가 1의자릿수도 있기때문에 4번 반복 후 slice(0, 4) 로 왼쪽부터 4자릿수로 끊어줍니다.
- x 에는 내부에 정의한 함수대로 정렬된 배열이 들어가고
- result 에는 그 배열을 문자로 치환하고 모든 문자의 합을 더하는 함수를 작성합니다.
프로그래머스 실행테스트 및 정확성테스트 모두 통과하였습니다.
질문하기에 다른 분들이 남겨준 예외상황이나 특수한 상황에 대한 힌트가 있었어서 풀 수 있었습니다.
세상엔 참 똑똑한 사람들이 많습니다. 힌트 감사합니다.
Step 7. 다른사람의 풀이
정말 심플합니다.
저와 다른점은 String 을 이용한 문자열 변환이 아닌 map() 메소드로 해결해 버렸네요
sort() 메소드 또한 저와는 다른 방식의 풀이 입니다.
그리고 전 reduce() 메서드를 이용했는데 join() 으로도 간단하게 합쳐버릴수가 있네요
마지막으로 삼항연산자를 사용하여 0의 예외처리와 답변 부분까지 깔끔하게 처리되었네요
댓글은 모두 환영하니 많이 달아주세요.
'지난포스트 (deprecated) > Algorithm & Data Structure (deprecated)' 카테고리의 다른 글
[정렬] K번째 수 with JS - Lv1 (0) | 2018.12.18 |
---|---|
[코딩테스트 연습] 위장 ★★ (0) | 2018.12.03 |
[코딩테스트연습] 완주하지 못한 선수 ★ (0) | 2018.12.01 |
2017 카카오 신입 공채 1차 코딩테스트 문제 풀이 (1번) (0) | 2018.11.05 |
python - 숫자 맞추기 게임(★☆☆☆☆) (0) | 2018.10.29 |