Algorithm/Leetcode

[Leetcode 937] Reorder Data in Log Files. - 문자열처리

EVO. 2023. 12. 7. 14:18

https://leetcode.com/problems/reorder-data-in-log-files/

Problem

로그를 재정렬하라. 기준은 다음과 같다.

 

1. 로그의 가장 앞부분은 식별자로서, 순서에 영향을 끼치지 않는다.

2. 문자로 구성된 로그가 숫자 로그보다 앞에 오며, 문자 로그는 사전순으로 한다.

3. 문자가 동일할 경우에는 식별자 순으로 한다.

4. 숫자 로그는 입력 순서대로 한다. 

 

Example

입력

logs = ["dig1 8 1 5 1","let1 art can","dig2 3 6","let2 own kit dig","let3 art zero"]

출력

["let1 art can","let3 art zero","let2 own kit dig","dig1 8 1 5 1","dig2 3 6"]

입력

logs = ["a1 9 2 3 1","g1 act car","zo4 4 7","ab1 off key dog","a8 act zoo"]

출력

["g1 act car","a8 act zoo","ab1 off key dog","a1 9 2 3 1","zo4 4 7"]

 

 

전략

문자 로그와 숫자 로그를 구분해 각각 처리한다.

문자로 구성된 로그가 숫자 로그보다 먼저 오며, 숫자 로그는 입력 순서대로 둔다. 문자 로그와 숫자 로그는 각각 정렬 방식이 다르므로, 둘을 아예 분리하고 각각 정렬한다음 나중에 결과로 서로 이어 붙이는 편이 한번에 처리하는 것보다 나을 것 같다. 

 

따라서 먼저 로그에서 식별자를 넘어간 첫번째 단어를 보고 문자로그인지 숫자로그인지 판단하고 각각의 리스트에 삽입한다.

문자로그의 정렬 기준은 사전순으로 하되, 문자가 동일할 경우 식별자 순으로 한다. 

 

문자 로그가 들어있는 리스트를 정렬할 때 Collections을 이용하고 sort()의 두 번째 인자에 Comparator를 이용하면 정렬조건을 설정하고 정렬할 수 있다. 아래는 식별자와 식별자가 아닌 부분을 나누고 먼저 식별자외 나머지를 사전순 비교를 하고 만약 같으면 식별자끼리 비교하도록 구현했다. 

public String[] reorderLogFiles(String[] logs) {
    List<String> letterList = new ArrayList<>();
    List<String> digitList = new ArrayList<>();

    for (String log : logs) {
        if (Character.isDigit(log.split(" ")[1].charAt(0))) {
            digitList.add(log);
        } else {
            letterList.add(log);
        }
    }

    Collections.sort(letterList, new Comparator<String>() {
        @Override
        public int compare(String s1, String s2) {
            String[] s1x = s1.split(" ", 2);
            String[] s2x = s2.split(" ", 2);

            int compared = s1x[1].compareTo(s2x[1]);
            if (compared == 0) {
                return s1x[0].compareTo(s2x[0]);
            } else {
                return compared;
            }
        }
    });

    letterList.addAll(digitList);
    return letterList.toArray(new String[0]);

}

 

자바 8부터는 익명 객체 대신에 람다식을 이용할 수 있기 때문에  최종적인 코드는 다음과 같다.

 

public String[] reorderLogFiles(String[] logs) {
        List<String> letterList = new ArrayList<>();
        List<String> digitList = new ArrayList<>();

        for (String log : logs) {
            if (Character.isDigit(log.split(" ")[1].charAt(0))) {
                digitList.add(log);
            } else {
                letterList.add(log);
            }
        }
        
        
        letterList.sort((s1, s2) -> {
            String[] s1x = s1.split(" ", 2);
            String[] s2x = s2.split(" ", 2);

            int compared = s1x[1].compareTo(s2x[1]);
            if (compared == 0) {
                return s1x[0].compareTo(s2x[0]);
            } else {
                return compared;
            }
        });

        letterList.addAll(digitList);
        return letterList.toArray(new String[0]);

    }

 

Comparator에서 구현하는 compare 메서드를 통해서 반환하는게 양수면 swap을 의미하고 음수면 그대로 swap을 하지 않는 것을 의미한다. 자세한 내용은 밑에 링크들에서 배울 수 있다.

 레퍼런스