본문 바로가기
Algorithm/Programmers

[고득점 Kit(정렬)] 가장 큰 수 (Swift, Python)

by 원만사 2022. 2. 3.
반응형

 

코딩테스트 연습 - 가장 큰 수

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요. 예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰

programmers.co.kr

 

풀이

 입력으로 주어진 numbers 배열을 String의 형태로 바꾸어 정렬을 해주는데 이때 새로운 기준이 되는 정렬 함수를 만들어 줘야 한다. 예를들어 예제의 [3, 30, 34, 5, 9]를 String 형태로 바꾸어 내림차순으로 정렬하면 [9, 5, 34, 30, 3]이 된다. 가장 큰 수를 만들기 위해서는 [9, 5, 34, 3, 30]으로 정렬이 되어야 한다.

 

 먼저 가장 앞의 숫자를 비교해서 같을 경우에는 길이를 따져본다. 만약 길이가 같을 경우에는 기존 정렬 방법대로 하면 된다. 즉, 30과 34의 경우에는 길이가 같으므로 34 ,30 순으로 정렬이 되도록 한다. 만약 길이가 다를 경우에는 두 문자열의 길이를 똑같이 맞춰준 후 비교한다. 예를 들어 342, 31을 비교할 때 342는 342342로 만들고 31은 313131로 만들어 두 문자열을 비교한다. 위의 예제에서 3과 30을 비교할 때 30과 33을 비교하게 되고 33이 더 크므로 3이 더 앞쪽에 위치하게 정렬할 수 있는 것이다. 

 

 마지막으로 numbers 배열이 0으로만 이루어져 있을 경우에는 단순히 "0"만 리턴하도록 예외처리를 해준다.

 

코드

[Swift]

import Foundation

// 정렬 함수
func numberCompare(_ a: String, _ b: String) -> Bool {
    if a == b { // 두 숫자가 같은 경우에는 그대로 리턴
        return true
    } else if a.first! > b.first! { // a의 첫 번째 숫자가 b의 첫 번째 숫자보다 클 경우에는 a가 앞에 정렬되도록 return
        return true
    } else if a.first! == b.first! { // a의 첫 번째 숫자와 b의 첫 번째 숫자와 같을 경우
        if a.count == b.count { // 둘의 길이가 같다면 더 큰 쪽이 앞에 정렬되도록 return
            if a > b {
                return true
            } else {
                return false
            }
        }
        
        // c는 a를 b의 길이만큼 repeat해준다.
        // d는 b를 a의 길이만큼 repaet해준다. a와 b의 길이를 일치시켜서 비교해주기 위한 과정
        // 최소공배수를 구해서 해줘도 되지만 그냥 둘을 곱했을 때의 길이를 가지도록 처리했다.
        let c: String = String(repeating: a, count: b.count)
        let d: String = String(repeating: b, count: a.count)
        
        // 이제 길이가 같은 문자열이므로 더 큰 쪽이 앞에 정렬되도록 처리
        if c > d {
            return true
        } else {
            return false
        }
    } else {
        return false
    }
}

func solution(_ numbers:[Int]) -> String {
    var strNumbers: [String] = [] // 입력으로 받은 numbers를 String 형태로 변경
    for n in numbers {
        strNumbers.append(String(n))
    }
    strNumbers.sort(by: numberCompare) // 위에서 정의한 정렬 기준으로 정렬
    
    // 만약 입력으로 받은 numbers가 0으로만 이루어져 있을 경우에는 "0" 리턴
    if numbers.filter({ $0 == 0 }).count == numbers.count {
        return "0"
    }
    
    // 이제 앞에서부터 순서대로 String으로 이어붙여서 리턴
    return strNumbers.reduce("") {
        return $0 + $1
    }
}

 

[Python]

from functools import cmp_to_key

# 정렬 함수
def numberCompare(a, b):
    if a == b: # 두 숫자가 같은 경우에는 그대로 리턴
        return 0
    elif a[0] > b[0]: # a의 첫 번째 숫자가 b의 첫 번째 숫자보다 클 경우에는 a가 앞에 정렬되도록 return
        return -1
    elif a[0] == b[0]: # a의 첫 번째 숫자와 b의 첫 번째 숫자와 같을 경우
        if len(a) == len(b): # 둘의 길이가 같다면 더 큰 쪽이 앞에 정렬되도록 return
            if a > b:
                return -1
            else:
                return 1

        # c는 a를 b의 길이만큼 repeat해준다.
        # d는 b를 a의 길이만큼 repaet해준다. a와 b의 길이를 일치시켜서 비교해주기 위한 과정
        # 최소공배수를 구해서 해줘도 되지만 그냥 둘을 곱했을 때의 길이를 가지도록 처리했다.
        c = a * len(b)
        d = b * len(a)

        # 이제 길이가 같은 문자열이므로 더 큰 쪽이 앞에 정렬되도록 처리
        if c > d:
            return -1
        else:
            return 1
    else:
        return 1


def solution(numbers):
    strNumbers = [str(x) for x in numbers] # 입력으로 받은 numbers를 String 형태로 변경
    strNumbers.sort(key=cmp_to_key(numberCompare)) # 위에서 정의한 정렬 기준으로 정렬

    # 만약 입력으로 받은 numbers가 0으로만 이루어져 있을 경우에는 "0" 리턴
    if numbers.count(0) == len(numbers):
        return '0'

    # 이제 앞에서부터 순서대로 String으로 이어붙여서 리턴
    return ''.join(strNumbers)
반응형

댓글