[2018 카카오 블라인드] 파일명 정렬 (JAVA)

Jiwoo Kim·2021년 3월 8일
0
post-thumbnail

문제


풀이

정렬을 잘 응용할 수 있는 지 확인할 수 있는 문제였다.
핵심 알고리즘인 정렬을 구현하는 데에는 1분도 걸리지 않았는데, 문자열을 파싱할 때 인덱스 찾는 데에서 오류가 계속 나서 디버깅하느라 시간이 좀 걸렸다. 그치만 풀어내서 참 뿌듯하다.

  1. parseFiles(): 주어진 filesFileName 리스트로 파싱한다.
    • getStartAndEndIndexOfNumber(): file에서 첫 번째로 등장하는 숫자의 시작과 끝 인덱스를 알아낸다.
    • 이 때 number의 길이는 5를 초과할 수 없기에 이 조건에 따라 endOfNumber를 조정한다.
    • 구해진 인덱스에 따라서 head, number, tail을 파싱한다.
    • FileName 객체를 생성하고 리스트에 저장한다.
  2. sort(): FileName 클래스의 compareTo()를 통해 FileName 리스트를 주어진 조건대로 정렬한다.
    • head를 알파벳 순으로 정렬할 때는 String 클래스의 compareToIgnoreCase()를 사용한다.
    • number를 정렬할 때는 Integer 클래스의 compare()를 사용한다.

코드

import java.util.*;

class Solution {
    
    private static final int START = 0;
    private static final int END = 1;

    public String[] solution(String[] files) {
        List<FileName> result = parseFiles(files);
        result.sort(FileName::compareTo);
        return buildStringArray(result);
    }

    private List<FileName> parseFiles(String[] files) {
        List<FileName> result = new ArrayList<>();
        for (String file : files) {
            int[] indexOfNumber = getStartAndEndIndexOfNumber(file);
            String head = file.substring(0, indexOfNumber[START]);
            String number = file.substring(indexOfNumber[START], indexOfNumber[END] + 1);
            String tail = parseTail(file, indexOfNumber[END] + 1);
            FileName fileName = new FileName(head, number, tail);
            result.add(fileName);
        }
        return result;
    }

    private int[] getStartAndEndIndexOfNumber(String file) {
        boolean isCurrentCharNumber = false;
        int startOfNumber = 0, endOfNumber = 0;
        for (int i = 0; i < file.length(); i++) {
            if (file.charAt(i) >= '0' && file.charAt(i) <= '9') {
                if (!isCurrentCharNumber) {
                    startOfNumber = i;
                    isCurrentCharNumber = true;
                }
            } else {
                if (isCurrentCharNumber) {
                    endOfNumber = i - 1;
                    break;
                }
            }
        }
        if (endOfNumber == 0) endOfNumber = file.length() - 1;
        if (isNumberLongerThanLimit(startOfNumber, endOfNumber)) endOfNumber = startOfNumber + 4;
        return new int[]{startOfNumber, endOfNumber};
    }

    private boolean isNumberLongerThanLimit(int startOfNumber, int endOfNumber) {
        return endOfNumber - startOfNumber > 4;
    }

    private String parseTail(String file, int startIndex) {
        if (startIndex < file.length()) return file.substring(startIndex);
        else return "";
    }

    private String[] buildStringArray(List<FileName> sortedFiles) {
        String[] result = new String[sortedFiles.size()];
        for (int i = 0; i < sortedFiles.size(); i++)
            result[i] = sortedFiles.get(i).fileName();
        return result;
    }
}

class FileName {
    String head;
    String number;
    String tail;
    int numberValue;

    public FileName(String head, String number, String tail) {
        this.head = head;
        this.number = number;
        this.tail = tail;
        this.numberValue = Integer.parseInt(number);
    }

    public String fileName() {
        return head + number + tail;
    }
    
    public static int compareTo(FileName o1, FileName o2) {
        if (o1.head.compareToIgnoreCase(o2.head) == 0)
            return Integer.compare(o1.numberValue, o2.numberValue);
        else
            return o1.head.compareToIgnoreCase(o2.head);
    }
}

0개의 댓글