[프로그래머스][Level 2][#17686] 파일명 정렬 해설

About

해설

정규표현식을 잘 구글링해서 풀었다. 솔직히 깔끔한 방법은 아니다.

(?<=\\D)(?=\\d)라는 정규표현식으로 숫자가 아닌 문자열과 숫자로 시작하는 문자열을 나눈다.

숫자로 시작하는 문자열은 다시 \\d+로 숫자만 걸러준다. 그 외의 부분은 버려도 좋다.

* 참고로, matcher.group()를 사용하면 match 결과 전체를 준다. 그룹을 지정했다면 매개변수로 그룹의 숫자를 넣어주면 된다.

그렇게 List에 하나씩 add 해주고, 나중에 정렬을 진행해 순서대로 반환한다.

정렬 기준은 클래스에서 Comparable 인터페이스를 implement 하고 compareTo를 오버라이딩하였다. 문제의 정의대로 순서대로 비교해주면 된다.

코드

GitHub

import java.util.*;
import java.util.regex.*;

public class Q17686 {

    public String[] solution(String[] files) {
        List<Node> list = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            String[] part = files[i].split("(?<=\\D)(?=\\d)");

            String head = part[0];
            String number = "";
            Pattern pattern = Pattern.compile("\\d+");
            Matcher matcher = pattern.matcher(part[1]);
            if (matcher.find()) {
                number = matcher.group();
            }

            Node node = new Node(i, files[i], head, number);
            list.add(node);
        }

        Collections.sort(list);
        return list.stream().map(n -> n.orig).toArray(String[]::new);
    }

    static class Node implements Comparable<Node> {
        int idx;
        String orig;
        String head;
        String number;

        @Override
        public String toString() {
            return "Node{" +
                    "idx=" + idx +
                    ", head='" + head + '\'' +
                    ", number='" + number + '\'' +
                    '}';
        }

        public Node(int idx, String orig, String head, String number) {
            this.idx = idx;
            this.orig = orig;
            this.head = head.toLowerCase();
            this.number = number;
        }

        @Override
        public int compareTo(Node o) {
            int order1 = this.head.compareTo(o.head);
            if (order1 != 0) {
                return order1;
            }

            int i1 = Integer.parseInt(this.number);
            int i2 = Integer.parseInt(o.number);
            int order2 = Integer.compare(i1, i2);
            if (order2 != 0) {
                return order2;
            }

            return Integer.compare(this.idx, o.idx);
        }
    }
}

2022-06-05