ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 항해2주차 - Node.js / Mission 4 코딩테스트 풀기 - 문자열 내 마음대로 정렬하기
    항해 2023. 1. 19. 18:21
    문제 설명
    문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
    제한 조건
    • strings는 길이 1 이상, 50이하인 배열입니다.
    • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
    • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
    • 모든 strings의 원소의 길이는 n보다 큽니다.
    • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다

    입출력 예

    strings n return
    ["sun", "bed", "car"] 1 ["car", "bed", "sun"]
    ["abce", "abcd", "cdx"] 2
    ["abcd", "abce", "cdx"]
    입출력 예 설명
    입출력 예 1 "sun", "bed", "car"의 1번째 인덱스 값은 각각 "u", "e", "a" 입니다. 이를 기준으로 strings를 정렬하면 ["car", "bed", "sun"] 입니다.
    입출력 예 2 "abce"와 "abcd", "cdx"의 2번째 인덱스 값은 "c", "c", "x"입니다. 따라서 정렬 후에는 "cdx"가 가장 뒤에 위치합니다. "abce"와 "abcd"는 사전순으로 정렬하면 "abcd"가 우선하므로, 답은 ["abcd", "abce", "cdx"] 입니다.
     
     
    해답 0 (그나마 이게 제일 이해 잘 감)
    function solution(strings, n) {
        var answer = [];
        strings.sort((a,b)=>{
            if(a[n]>b[n]){
                return 1
            } else if(b[n]>a[n]){
                return -1
            } else if(a[n]==b[n]){
                if(a>b){
                    return 1
                } else if(a<b){
                    return -1
                }   else{
                    return 0
                }
            }
        })
        return strings
    }
     
    해답 1
    function solution(strings, n) {
        strings.sort(function(a,b){
            if(a[n] > b[n]) return 1;
            if(b[n] > a[n]) return -1;
    
            if(a > b) return 1;
            if(b > a) return -1;
    
            return 0;
        });
        return strings;
    }

    해답 2

    function solution(strings, n) {
        return strings.sort().sort((a,b) => a.charCodeAt(n)-b.charCodeAt(n));
    }
    • 먼저 소트를 해서, 똑같거나 비슷한 놈들에 대한 정리를 한 후에, 자리 비교를 하는 쪽으로 했습니다. 소트가 두 번이라 불필요한 연산이 들어있을 것 같은데, localeCompare 라는 메소드가 있는 것을 몰랐어서 그냥 이렇게 했습니다. 다만 왠지 모르겠지만 localeCompare를 사용해서 소트를 1번만 해본 결과 속도가 3배정도 더 걸리네요. 결과적으로는 소트를 두번 쓰는것이 더 간결, 더 빠른 것 같은데 왜그런지 아시는 분 계실까요?!
    • 고로 리턴 후의 부분을 strings.sort().sort((a,b) => a.charCodeAt(n)-b.charCodeAt(n)|a.localeCompare(b)); 이렇게 둘이 같을 경우에는 false가 리턴 되므로 뒤의 localeCompare가 작동되도록 해봤더니 더 느렸습니다.

    해답3

    function solution(strings, n) {
        var answer = [];
        var indexList = [];
        // strings.forEach(function(value,index){
        //     indexList.push({compare:value[n], value: value});
        // });
    
        /*
        {index: 0, compare:u, value: sun}
        {index: 1, compare:e, value: bed}
        {index: 2, compare:a, value: car}
        */
    //     indexList.sort(function(a,b){
    //         if (a.compare > b.compare) return 1;
    //         if (b.compare > a.compare) return -1;
    
    //         if(a.value > b.value) return 1;
    //         if(b.value > a.value) return -1;
    //         return 0;
    //     });
        /*
        {index: 2, compare:a, value: car}
        {index: 1, compare:e, value: bed}
        {index: 0, compare:u, value: sun}
        */
    
        strings.sort(function(a,b){
            if(a[n] > b[n]) return 1;
            if(b[n] > a[n]) return -1;
    
            if(a > b) return 1;
            if(b > a) return -1;
    
            return 0;
        });
    
        // indexList.forEach(function(value){
        //     answer.push(value.value);
        // });
        return strings;
    }

    해답 4

    function solution(strings, n) {
        var answer = [];
        for (var i = 0; i < strings.length; i++) {
            var chu = strings[i][n];
            strings[i] = chu + strings[i];
        }
        strings.sort();
        for (var j = 0; j < strings.length; j++) {
            strings[j] = strings[j].replace(strings[j][0],"");
            answer.push(strings[j])
        }
    
        return answer;
    }
    • replace 말고 substr도 있어요
    • 내부 인덱스 값 앞에 붙이고 그걸 기준으로 정렬 + 앞에 붙인 값 제거를 하셨네요
    • 필요한 정렬 두 가지를 (내부 인덱스 기준 정렬 + 남는 전체 string 정렬) 한번에 할 수 있네요!

    해답 5

    function solution(strings, n) {
        return strings.sort((a, b) => {
            const chr1 = a.charAt(n);
            const chr2 = b.charAt(n);
    
            if (chr1 == chr2) {
                return (a > b) - (a < b);
            } else {
                return (chr1 > chr2) - (chr1 < chr2);
            }
        })
    }
    • sort함수 안에 들어가는 compareFunction은 함수에게 배열의 2개의 요소를 받습니다(보통 a,b라고 많이 지정하죠). 이 2개를 반복해서 보낸뒤 compatreFuntion이 반환하는 값을 기준으로 정렬합니다. 반환값>0이면 a가 b보다 앞에 있어야하고, 반환값=0이면 a와 b의 순서를 바꾸지 않는다. 반환값<0이면 b가 a보다 앞으로 순서를 바꾼다. 이런식으로요. 그런데 윗분들이 말씀하셨듯 자바스크립트에서 true=1, false=0입니다. 즉, (a > b) - (a < b); 이 식은 a가 b보다 크면 b가 a보다 앞에 있어야한다(리턴값 = 1) 또는, b가 a보다 크면 a는 b보다 앞으로 와야한다(리턴값 = -1)라는 식으로 해석될 수 있고, 이건 compareFuntion을 아무것도 쓰지 않은 기본적인 sort()와 똑같이 동작합니다.
    • 뭐.. 쉽게 그냥 한줄로 풀어말해서 sort([compareFuntion])에서 compareFuntion안에 똑같은 sort를 또 쓸 수 없으니 기본 sort()의 동작방식을 식으로 쓴 것 뿐입니다.
    • 밑에 chr을 통한 비교는 자리수에 대한 비교, 위에 ab 비교는 전체 스트링에 대한 비교라고 볼 수 있겠군요. 즉 chr이 같은 경우 즉 n번째 문자가 같은 경우에는 문자열에 따라 정렬하겠고, 그 외의 경우는 지정한 문자를 보며 정렬한다.
    • 저도 이거 보고 처음 알았는데 true - false = 1 이네요 ㄷㄷ 꼭 sort 함수 안에서만이 아닌 듯

    댓글

Designed by Tistory.