본문 바로가기

Algorithm/Programmers

[2018 KAKAO BLIND RECRUITMENT][문자열 처리/PQ] 파일명 정렬 - Java

문제 바로가기

 

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

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

programmers.co.kr

 

많이 어렵지 않은 문제입니다. 문자열을 이쁘게 자르는게 관건입니다.

import java.util.*;

class Solution {
    static class File implements Comparable<File> {
        String name, head, tail;
        int order, number;

        File(String filename, int order){
            this.name = filename;
            this.order = order;

            StringBuilder sb = new StringBuilder();

            for(int i = 0; i < filename.length(); i++) {
                if('0' <= filename.charAt(i) && filename.charAt(i) <= '9') {
                    this.head = sb.toString();
                    sb.delete(0, sb.length());


                    for(int j = i; j < i + 5; j++) {
                        if(filename.length() <= j) {                        // TAIL 없는 경우
                            this.number = Integer.parseInt(sb.toString());
                            this.tail = "";
                            return;
                        }
                        if('0' <= filename.charAt(j) && filename.charAt(j) <= '9') {
                            sb.append(filename.charAt(j));
                        }else {                                                // NUMBER 끝
                            i = j;
                            break;
                        }
                    }

                    this.tail = sb.length() == 5 ? filename.substring(i+5) : filename.substring(i);
                    this.number = Integer.parseInt(sb.toString());

                    break;
                }
                sb.append(filename.charAt(i));
            }
        }

        // 정렬 기준: HEAD -> NUMBER -> 들어온 순서 
        public int compareTo(File o) {
            if(this.head.toLowerCase().equals(o.head.toLowerCase())) {
                if(this.number == o.number) return this.order - o.order;
                return this.number - o.number;
            }
            return this.head.toLowerCase().compareTo(o.head.toLowerCase());
        }
    }

    public String[] solution(String[] files) {
        String[] answer;
        PriorityQueue<File> pq = new PriorityQueue<>();

        for(int i = 0; i < files.length; i++) {
            File file = new File(files[i], i);
            pq.offer(file);
        }

        answer = new String[files.length];
        int idx = 0;

        while(!pq.isEmpty()) {
            answer[idx++] = pq.poll().name;
        }

        return answer;
    }
}

File 이란 클래스를 선언해서 써먹었습니다. 멤버 변수로는 answer에 넣을 name, HEAD, NUMBER, TAIL, 그리고 마지막 정렬 기준인 들어온 순서(order)가 있습니다.

 

정답은 files의 원소인 문자열(파일 이름)들을 하나씩 갖고와서 File 인스턴스로 만들어서 우선순위 큐에 넣어주고 순서대로 빼주면 쉽게 구할 수 있습니다.

 

관건은 앞서 말했듯이 문자열 처리입니다.. 제 코드는 상당히 더럽습니다. ㅜ

TAIL이 없는 경우와 중간의 숫자의 길이가 5를 넘어가는 경우를 신경써야 합니다!! 

 

 

문자열을 갖고 노는건 아직 서툽니다 ㅜ

감사합니다 화이팅!!