Coding Test/프로그래머스

[210123] 파일명 정렬- 2018 KAKAO BLIND RECRUITMENT

csmoon1010 2021. 1. 23. 15:56

0. 문제유형 : 문자열 활용

1. 문제이해

programmers.co.kr/learn/courses/30/lessons/17686

 

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

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

programmers.co.kr

(1) 주요 요구사항

 

파일명의 구분 : HEAD, NUMBER, TAIL

- HEAD : 숫자가 아닌 문자, 최소 1글자 이상

- NUMBER : 1~5 글자 사이의 연속된 숫자, 앞쪽에 0이 올 수 있다. (0 ~ 99999)

- TAIL : 나머지 부분, 아무 글자도 없을 수도 있음 (런타임 오류 났었던 이유!)

 

 파일명 정렬 규칙

(STEP 1) HEAD를 기준으로 사전 순 정렬, 대소문자 구분X

(STEP 2) NUMBER의 숫자 크기 순으로 정렬 (ex. 9<10<0011<012<13<014)

(STEP 3) HEAD와 NUMBER의 숫자도 같으면, 원래 입력에 주어진 순서를 유지

 

 

 

(2) 제약사항

 

① files : 파일명 목록

- 100글자 이내

- 영문 대소문자, 숫자, 공백(""), 마침표("."), 빼기 부호("-")로 이루어짐

- 영문자로 시작, 숫자 하나 이상

- 1000개 이하의 파일명 포함, 중복된 파일명은 없음

 

 

 

 

 

 

 

2. 전략

 

① HEAD, NUMBER, TAIL 분리 : public String[][] splitName(String[] files, int size)

: 조건에 맞게 분리하여 2차원 배열(answer)에 저장

- HEAD(answer[i][0]) : 처음부터 숫자가 아닌 문자가 나올 때까지 (h) 

    > Character.isDigit() 이용

- NUMBER(answer[i][1]) : h부터 숫자인 문자가 나오고, h+5보다 작으며, 전체 길이를 넘어가지 않을 때까지 (n)

- TAIL(answer[i][2]) : 나머지 부분 (n~)

 

 

② 파일명 정렬 : Comparator 객체 활용

 

(STEP 1) 소문자로 변경(toLowerCase) 후 compareTo를 이용해 사전 순 정렬

(STEP 2) int형으로 변경(Integer.parseInt) 후 숫자 차를 이용해 오름차순 정렬 (앞 요소가 먼저 오게!)

 

 

 

 

 

 

 

3. 참고사항

 

① Comparator 기본 구조

- 익명 클래스 활용

Arrays.sort(sfiles, new Comparator<E>(){
    public int compare(E e1, E e2){
        ...
    }
}

 

 

- 클래스 정의

public Class 클래스명 implements Comparator<E> {
    @Override
    public int compare(E e1, E e2){
        ...
    }
}

 

 

② HEAD 분리

: 숫자 집합을 의미하는 regex 이용 가능

String HEAD = files[i].split("[0-9]")[0];

String head = str.split("[0-9]")[0];
str = str.replace(head, "");
head = head.toLowerCase();

String number = "";
for(char c : str.toCharArray()){
    if(Character.isDigit(c) && number.length() < 5){
        number += c;
    }
    else	break;
}

 

 

 

 

 

 

 

 

4. 코드

import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String[] solution(String[] files) {
        int size = files.length;
        String[] answer = new String[files.length];
        String[][] sfiles = splitName(files, size);
        Arrays.sort(sfiles, new Comparator<String[]>(){
            public int compare(String[] s1, String[] s2){
                int answer = 0;
                String h1 = s1[0].toLowerCase(); String h2 = s2[0].toLowerCase();
                if(!h1.equals(h2))  answer = h1.compareTo(h2);
                else{
                    int n1 = Integer.parseInt(s1[1]);
                    int n2 = Integer.parseInt(s2[1]);
                    answer = n1-n2;
                }
                return answer;
            }
        });
        for(int i = 0; i < size; i++){
            answer[i] = sfiles[i][0] + sfiles[i][1] + sfiles[i][2];
        }
        return answer;
    }
    
    public String[][] splitName(String[] files, int size){
        String[][] answer = new String[size][3];
        for(int i= 0; i < size; i++){
            int nameL = files[i].length();
            int h = 0; int n = 0;
            for(h = 0; h < nameL; h++){
                if(Character.isDigit(files[i].charAt(h)))  break;
            }
            for(n = h; n < h+5 && n < nameL; n++){ //예외 CASE 생각 또 못함
                if(!Character.isDigit(files[i].charAt(n))) break;
            }
            answer[i][0] = files[i].substring(0, h);
            answer[i][1] = files[i].substring(h, n);
            answer[i][2] = files[i].substring(n, nameL);
        }
        return answer;
    }
}