[210123] 파일명 정렬- 2018 KAKAO BLIND RECRUITMENT
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;
}
}