Algorithm
프로그래머스
Java
파일명 정렬

파일명 정렬

내 풀이

  • String은 compareTo를 사용해서 정렬한다.
  • List<String>을 String[]으로 변환할 때 toArray(String[]::new)를 사용한다.
  • s1 문자열의 경우 숫자가 나온 경우 length를 넘어서서 numRanges[1]이 0인채 for loop이 끝나게 되는데 이를 처리해주기 위해 분기가 하나 더 필요했다.
import java.util.*;
 
class Solution {
    public String[] solution(String[] files) {
        String[] ans = Arrays.stream(files)
                .sorted(new Comparator<String>() {
                    @Override
                    public int compare(String s1, String s2) {
                        int[] numRanges = new int[4];
                        int max = Collections.max(List.of(s1.length(), s2.length()));
                        for (int i = 0; i < max; i++) {
 
                            if(s1.length() > i) {
                                if (s1.length() > i && numRanges[0] == 0 && Character.isDigit(s1.charAt(i))) {
                                    numRanges[0] = i;
                                } else if (s1.length() > i && numRanges[0] != 0 && numRanges[1] == 0) {
                                    if (!Character.isDigit(s1.charAt(i))) {
                                        numRanges[1] = i;
                                    } else if (s1.length() - 1 == i || numRanges[0] + 4 == i) {
                                        numRanges[1] = i + 1;
                                    }
                                }
                            }
 
                            if(s2.length() > i) {
                                if (s2.length() > i && numRanges[2] == 0 && Character.isDigit(s2.charAt(i))) {
                                    numRanges[2] = i;
                                } else if (s2.length() > i && numRanges[2] != 0 && numRanges[3] == 0) {
                                    if (!Character.isDigit(s2.charAt(i))) {
                                        numRanges[3] = i;
                                    } else if (s2.length() - 1 == i || numRanges[2] + 4 == i) {
                                        numRanges[3] = i + 1;
                                    }
                                }
                            }
 
                            if (numRanges[0] != 0 && numRanges[1] != 0 && numRanges[2] != 0 && numRanges[3] != 0) {
                                break;
                            }
                        }
                        if(numRanges[1] == 0) {
                            numRanges[1] = s1.length();
                        }
                        if(numRanges[3] == 0) {
                            numRanges[3] = s2.length();
                        }
                        String HEAD1 = s1.substring(0, numRanges[0]);
                        int NUM1 = Integer.parseInt(s1.substring(numRanges[0], numRanges[1]));
                        String HEAD2 = s2.substring(0, numRanges[2]);
                        int NUM2 = Integer.parseInt(s2.substring(numRanges[2], numRanges[3]));
                        Integer headCompareResult = HEAD1.toUpperCase().compareTo(HEAD2.toUpperCase());
                        if (headCompareResult != 0) {
                            return headCompareResult;
                        } else if (headCompareResult == 0) {
                            return Integer.compare(NUM1, NUM2);
                        }
                        return 0;
                    }
                })
                .toArray(String[]::new);
 
        return ans;
    }
}

개선된 풀이

import java.util.*;
 
class Solution {
    public String[] solution(String[] files) {
        return Arrays.stream(files)
            .sorted((s1, s2) -> {
                String[] parsed1 = parseFileName(s1);
                String[] parsed2 = parseFileName(s2);
                int headCompare = parsed1[0].compareToIgnoreCase(parsed2[0]);
                if (headCompare != 0) return headCompare;
                return Integer.compare(Integer.parseInt(parsed1[1]), Integer.parseInt(parsed2[1]));
            })
            .toArray(String[]::new);
    }
 
    private String[] parseFileName(String file) {
        int firstDigit = -1;
        int length = file.length();
        for (int i = 0; i < length; i++) {
            if (Character.isDigit(file.charAt(i))) {
                firstDigit = i;
                break;
            }
        }
 
        int lastDigit = firstDigit;
        while (lastDigit < length && Character.isDigit(file.charAt(lastDigit)) && lastDigit - firstDigit < 5) {
            lastDigit++;
        }
 
        String head = file.substring(0, firstDigit);
        String number = file.substring(firstDigit, lastDigit);
        return new String[]{head, number};
    }
}