[자바스크립트/알고리즘] 프로그래머스 - 파일명 정렬: 2018 카카오 블라인드
728x90

[문제]

 

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

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

programmers.co.kr

1. 저장소 서버에는 프로그램의 과거 버전을 모두 담고 있어, 이름 순으로 정렬된 파일 목록은 보기가 불편했다.  또한, 버전 번호 외에도 숫자가 포함된 파일 목록은 여러 면에서 관리하기 불편했다.

2. 무지는 단순한 문자 코드 순이 아닌, 파일명에 포함된 숫자를 반영한 정렬 기능을 저장소 관리 프로그램에 구현하기로 했다.

3. 파일명은 크게 HEAD, NUMBER, TAIL의 세 부분으로 구성된다.

4. 무지를 도와 파일명 정렬 프로그램을 구현하라.

 

[주의]

파일명을 세 부분으로 나눈 후, 다음 기준에 따라 파일명을 정렬한다.

  • 파일명은 우선 HEAD 부분을 기준으로 사전 순으로 정렬한다. 이때, 문자열 비교 시 대소문자 구분을 하지 않는다. MUZI와 muzi, MuZi는 정렬 시에 같은 순서로 취급된다.
  • 파일명의 HEAD 부분이 대소문자 차이 외에는 같을 경우, NUMBER의 숫자 순으로 정렬한다. 9 < 10 < 0011 < 012 < 13 < 014 순으로 정렬된다. 숫자 앞의 0은 무시되며, 012와 12는 정렬 시에 같은 같은 값으로 처리된다.
  • 두 파일의 HEAD 부분과, NUMBER의 숫자도 같을 경우, 원래 입력에 주어진 순서를 유지한다. MUZI01.zip과 muzi1.png가 입력으로 들어오면, 정렬 후에도 입력 시 주어진 두 파일의 순서가 바뀌어서는 안 된다.

 

[코드 풀이 & 해설]

function solution(files) {
    var answer = [];
    let fileArr = [];
    for(const file of files){
        let headNum = file.match(/(\D+)(\d{1,5})/);
        let [,head, num] = headNum; // headNum에서 찾은 head와 number 구조 분해 할당
        let tail = file.split(head+num)[1];
        fileArr.push([head, num, tail]);
    }
    fileArr.sort((a,b)=>{
        const lowA = a[0].toLowerCase();
        const lowB = b[0].toLowerCase();
        
        // 1. 두 파일의 head와 number가 같을 경우 원래 입력에 주어진 순서 유지
        if(lowA === lowB && Number(a[1]) === Number(b[1])) return 0;
        // 2. 대소문자 차이 외에 숫자가 다르다면 숫자 순으로 정렬
        if(lowA === lowB) return Number(a[1]) - Number(b[1])
        // 3. 위의 두 경우에 해당하지 않는다면, head부분을 기준으로 사전순 정렬
        return lowA.localeCompare(lowB)
    })
    for(const file of fileArr) answer.push(file.join(''))
    
    return answer;
}

정규식을 사용하여 head와 number를 찾아 headNum에 넣어주고, 다음 라인에서 구조 분해 할당으로 head와 num으로 나누어 주었다.

tail은 head와 number을 제외한 나머지 부분이므로 split으로 나눈 다음에 할당해주었다.

 

위 과정을 통해 한 파일의 head, number, tail을 배열로 묶어 fileArr에 넣어주었다. 

즉 fileArr은 주어진 파일들의 [head, num, tail]의 묶음이다.

 

파일의 정보가 담겨있는 fileArr을 정렬하는데, 위에서 언급하였던 주의사항을 기준으로 한다.

대소문자 구분을 하지않기 위해 주어진 파일 두 개의 name을 소문자로 바꾸고, 비교한다.

1. 두 파일의 head와 number가 같을 경우 원래 입력에 주어진 순서를 유지한다.

2. 대소문자 차이 외에 숫자가 다르다면 숫자 순으로 정렬해준다.

3. 위의 두 경우에 해당하지 않는다면, head부분을 기준으로 사전 순 정렬한다.

 

즉, 주의 부분에서 언급하였던 세 가지 경우를 거꾸로 해주었다!!

 

마지막으로 head, num, tail을 문자열로 묶어서 정답 배열에 넣어 반환한다!

320x100