개발하는 두부

[Programmers] 파일명 정렬 (Java)

by 뚜부니

 

 

코딩테스트 연습 - [3차] 파일명 정렬

파일명 정렬 세 차례의 코딩 테스트와 두 차례의 면접이라는 기나긴 블라인드 공채를 무사히 통과해 카카오에 입사한 무지는 파일 저장소 서버 관리를 맡게 되었다. 저장소 서버에는 프로그램

programmers.co.kr

이 문제는 파일명을 특정 조건에 맞춰 자른 후 정렬하는 문제로,

처음 등장하는 숫자를 기준으로 HEAD, NUMBER, TAIL로 나눕니다.

그러니까 문자, 처음 등장하는 숫자, 최대 길이 5, 문자로 HEAD, NUMBER, TAIL을 나누는 형태입니다.

 

HEAD 부분 문자를 기준으로 사전순 정렬을 하는데, 이 때 대소문자는 구분하지 않습니다.

만약, HEAD 부분의 문자가 MUZI, muzi와 같은 형태라면 동일한 순서로 취급되므로 NUMBER를 확인합니다.

NUMBER가 00001과 같은 형태라면, 앞의 0은 무시되며 1로 취급하여 계산을 합니다. (int형으로 변경)

만약, HEAD 부분과 NUMBER의 숫자가 모두 같으면, 원래 입력에 주어진 순서를 유지합니다.

그 후, 변경된 순서에 맞춰 정렬된 배열을 출력하는 문제입니다.

 

조건에 따른 정렬을 하기 위해서는 Comparator를 구현하면 됩니다.

들어오는 두 문자에 대해 숫자를 기준으로 앞부분만 가져오면 되므로

정규식 표현을 이용해 숫자를 기준으로 잘라준 후 0번 인덱스를 가져옵니다.

그 후 compareTo를 사용해 비교를 하는데, 이 때 대소문자를 구분하지 않기 위해 모두 소문자로 변경해줍니다.

변경된 소문자를 기준으로 두 문자를 비교하였을 때,

문자1 > 문자2인 경우 양수, 문자1 < 문자2인 경우 음수, 문자1==문자2인 경우 0을 반환합니다.

0을 반환하지 않은 경우 그대로 리턴시키면, Comparator가 수행됩니다. 양수라면 자리가 변경되겠죠!

그러나 0인 경우에는 숫자에 대한 비교가 필요합니다.

HEAD 길이만큼 제외시킨 다음, 숫자에 대해서 길이가 최대 5가 될때까지 찾습니다.

그 후, 찾은 숫자(문자열 형태)를 정수형으로 변경하여 반환하는 함수를 만들어줍니다.

이렇게 반환된 두 숫자를 비교하여 Comparator를 수행합니다.

 

위와 같은 형태로 코드를 작성하면 다음과 같습니다.

import java.util.*;

class Solution {
    public String[] solution(String[] files) {
        String[] answer = {};
        
        // 조건에 따른 정렬을 하기 위해 Comparator 구현
        // compare 리턴값이 양수면 두 객체의 자리를 바꿔줌
        Arrays.sort(files, new Comparator<String>(){
            @Override
            public int compare(String o1, String o2) {
                // 숫자 앞부분을 잘라서 head 생성
                String head1 = o1.split("[0-9]")[0];
                String head2 = o2.split("[0-9]")[0];
                
                // compareTo를 사용한 비교를 위해서는 모두 소문자로 변경 후 비교
                int result = head1.toLowerCase().compareTo(head2.toLowerCase());
                
                if (result == 0) { // 같은 문자일 경우 숫자로 비교
                    result = convertNum(o1, head1) - convertNum(o2, head2);
                }
                
                return result;
            }
        });
        
        return files;
    }
    
    public int convertNum(String str, String head) {
        str = str.substring(head.length()); // head 길이만큼 잘라서 숫자부터 시작하게 만들어줌
        String result = "";
        for (char c : str.toCharArray()) {
            if (Character.isDigit(c) && result.length() < 5) // 숫자인지 그리고 result 길이가 5가 안 넘는지 확인
                result += c;
            else
                break;
        }
        return Integer.valueOf(result);
    }
}

블로그의 정보

개발하는 두부

뚜부니

활동하기