[JS][프로그래머스LV2]파일명 정렬
Algorithm/Programmers

[JS][프로그래머스LV2]파일명 정렬

문제 번호

 

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

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

programmers.co.kr

 

 

알고리즘 분류

 

 

문제 풀이

 문제에서 주어진 조건대로 정렬을 사용해야하는 문제이다. 특별히 어려운 알고리즘은 없지만 조건이 여러개라서 잘 보고 천천히 풀면 된다.

 

 나는 빈 배열을 생성하여 배열에 head, number, tail 프로퍼티로 이루어진 객체들을 push 한 뒤 정렬하는 방법을 선택하였다.

 

우선 입력받은 files 배열을 빈 배열인 file 배열에 넣어준다.

    let file = [];
    
    // 주어진 파일들을 입력받는 부분.
    for(let i=0; i<files.length; i++){                
        let head = /^[\D]*/g.exec(files[i])[0];
        files[i] = files[i].replace(/^[\D]*/g,'');
        
        let number = /[\d]*/g.exec(files[i])[0]; 
        files[i] = files[i].replace(/[\d]*/,'');
                
        let tail = files[i];        
        file.push( {'head':head, 'number':number, 'tail':tail});
    }

 

* match 메서드를 사용하면 더 간단하게 입력받는 방법도 있더라. match 메서드는 반환값으로 배열을 반환하는데 첫번째 요소로 찾고자 하는 내용과 일치하는 문자열이 오고 뒤이어 괄호에 해당하는 내용들이 들어가있다. 일치하는 것이 없으면 null 이 반환된다. 괄호와 일치하는 것이 없을때는 빈 문자열이 반환됐다.

const reg = /(\D*)([0-9]*)/i;
const A = a.match(reg);
 

String.prototype.match() - JavaScript | MDN

match() 메서드는 문자열이 정규식과 매치되는 부분을 검색합니다.

developer.mozilla.org

 

배열에 값을 넣어줬으니 문제에서 요구하는대로 정렬만 하면된다. 나는 JS에서 주어지는 sort 함수를 사용하였는데 JS의 sort 는 불안정 sort이다.

 

안정 정렬 vs 불안정 정렬

KTX 역에서 도착역과 출발 시간으로 이루어진 다음과 같은 데이터가 있다고 가정해 봅시다. [(대구, 1400), (순천, 1500), (대구, 1430), (부산, 1300), (목포, 1400), (대구, 1500)] 지역명으로 오름차순으로 정

hongl.tistory.com

// head 부분 기준 사전 순 정렬.
    file.sort((a,b) => {
        let aHead = a.head.toLowerCase();
        let bHead = b.head.toLowerCase();
        if(aHead < bHead) return -1;
        else if(aHead > bHead) return 1;
        else {
            let aNumber = parseInt(a.number);
            let bNumber = parseInt(b.number);            

            if(aNumber < bNumber) return -1;
            else if(aNumber > bNumber) return 1;
            else return 0;
        }
    })

다른 분들의 풀이를 보니 localeCompare를 사용하는 모습도 많이 볼 수 있었다.

 

String.prototype.localeCompare() - JavaScript | MDN

The localeCompare() 메서드는 기준 문자열과 비교했을 때 비교 대상 문자열이 정렬상 전에 오는지, 후에 오는지 혹은 같은 순서에 배치되는지를 알려주는 숫자를 리턴합니다.

developer.mozilla.org

 

마지막으로 정렬이 완료된 배열을 answer 배열에 넣어서 반환하면 마무리된다.

    for(let i=0; i<file.length; i++){
        let fileName = file[i].head + file[i].number + file[i].tail;
        answer.push(fileName);
    }

 

전체코드

function solution(files) {
    var answer = [];    
    let file = [];
    
    // 주어진 파일들을 입력받는 부분.
    for(let i=0; i<files.length; i++){                
        let head = /^[\D]*/g.exec(files[i])[0];
        files[i] = files[i].replace(/^[\D]*/g,'');
        
        let number = /[\d]*/g.exec(files[i])[0]; 
        files[i] = files[i].replace(/[\d]*/,'');
                
        let tail = files[i];        
        file.push( {'head':head, 'number':number, 'tail':tail});
    }   
   
    
    // head 부분 기준 사전 순 정렬.
    file.sort((a,b) => {
        let aHead = a.head.toLowerCase();
        let bHead = b.head.toLowerCase();
        if(aHead < bHead) return -1;
        else if(aHead > bHead) return 1;
        else {
            let aNumber = parseInt(a.number);
            let bNumber = parseInt(b.number);            
            
            if(aNumber < bNumber) return -1;
            else if(aNumber > bNumber) return 1;
            else return 0;
        }
    })
    
    for(let i=0; i<file.length; i++){
        let fileName = file[i].head + file[i].number + file[i].tail;
        answer.push(fileName);
    }
    
    return answer;
}

 

특이사항

 C++로 준비했을때는 못풀었던 문제였는데 JS를 준비하면서 풀어보니까 1시간 이내에 푼거같다.

정규식에 좀더 익숙했더라면 시간을 훨씬 더 줄일 수 있었다.