Programmers / 문자열 내림차순으로 배치하기 - 12917

y1nlog·2025년 1월 2일
1

[level 1] 문자열 내림차순으로 배치하기 - 12917

문제 설명

문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요.
s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주합니다.

제한 사항
str은 길이 1 이상인 문자열입니다.

입출력 예
s--------- return
"Zbcdefg" "gfedcbZ"

풀이

  • 예시 테스트케이스 1개만 맞춘 코드
function solution(s){
    var answer = [...s].sort(function(a,b){
        return b.localeCompare(a);
    })
    answer.forEach(x => {
        if(x === x.toUpperCase()){
            answer.splice(answer.indexOf(x),1);
            answer.push(x);
        }
    })
    return answer.join('');
}
입력값 s, "Zbcdefg"를 [...s](Spread operator)를 이용해 배열화부터 한 후
sort를 내림차순으로 수행해 주어 answer라는 변수에 할당한다.
이후 answer의 각 요소를 순회하면서, 해당 요소가 대문자인지를 검증, 만일 대문자라면 
Boolean 값을 반환할 조건 `(x === x.toUpperCase())`에서 True가 나오고
순차적으로 해당 값의 indexOf로 배열에서 삭제 후 push하는 흐름이다.
그런데,,, 예시 테케 1번만 맞출 줄이야...
  • 생성형 AI 풀이
function solution(s) {
    // 소문자와 대문자를 분리하여 각각 정렬
    const lowerCase = [...s].filter(x => x === x.toLowerCase()).sort((a, b) => b.localeCompare(a));
    const upperCase = [...s].filter(x => x === x.toUpperCase()).sort((a, b) => b.localeCompare(a));
    
    // 정렬된 소문자와 대문자를 합침 (문제 조건에 따라 소문자가 앞에 오도록)
    return [...lowerCase, ...upperCase].join('');
}

메모리: 36.2 MB, 시간: 10.74 ms

AI의 도움을 받아보았다. lowerCase / upperCase로 대소문자를 나누어 정렬을 진행하면,
내가 고전했던 예시 테케 속 Z의 처리가 쉬울 것 같았다.
여기서 받은 로직은 프롬프트에 내가 위의 코드로 학습을 시켰기 때문에, 비슷한 느낌으로
spread operator와 toUpperCase, sort가 보이는 모습이다. 역시 AI 학습의 중요성을 다시
한 번 느낀다. 무튼, 각각 분리해 filter 조건으로 각 요소들이 소문자인지, 대문자인지 구분해 
const 변수에 담아주고, 각각 정렬을 수행하여 순서대로 return해주는 코드였다.

다른 사람의 풀이

function solution(s) {
    return s
        .split('')
        .sort()
        .reverse()
        .join('')
}

메모리: 33.5 MB, 시간: 0.22 ms

이런 고전을 겪고서 가장 위에 있는 코드를 보고, 몰려드는 배신감에 이 코드를 가져와서 돌려봤다.
어쩜 ... 메모리 사용량도 개선이 되었고, 처리시간에서 5배가량 차이난다. 역시 코드를 야무지게
쓰는 게 중요하단 걸 체감하는 순간이었다...
코드를 보면 input값을 split하여 배열로 저장, 이후 정렬 수행(compareFunction의 부재로
기본적인 오름차순 정렬이 수행된다). 우리는 내림차순 정렬이기 때문에 reverse() 이용하여 그냥 
뒤집어주고, join을 통한 String 값 return까지...
나는 reverse를 안 썼던 이유가, 일단 대문자 값들이 앞에 있는 상황에서 reverse를 하면 대문자 
안의 정렬이 흩어지지 않을까? 해서 그냥 사용을 안했었는데.. 이 코드가 모든 걸 뚫어버린 걸 보고
이제 간단한 예시라도 들어서 분석하고 코드를 짜야겠다는 생각을 했다. 충격 그 자체..ㅋㅋㅋ

노트

오늘 새롭게 본 자바스크립트 메소드를 정리해보고 넘어 가겠다.

localeCompare() : 문자열 비교

  • 알파벳 순서대로 비교
  • 대소문자 구분
  • 언어별 특수문자 정렬 가능
'a'.localeCompare('b'); // -1 (음수): a가 b보다 앞에 옴
'b'.localeCompare('a'); // 1 (양수): b가 a보다 뒤에 옴
'a'.localeCompare('a'); // 0: 동일함

알파벳 순서 사실 외우기 진짜 귀찮아서.. 처음에 코드 쓸 때
변수에 'abcdefghijk...'노래 부르면서 쓰고있었다. 그리고 그거 역으로 쓰긴 싫어서 reverse를 써보고 이래저래 하고 있었는데, localeCompare를 AI가 알려주어서 이번 기회에 첫 사용을 해봤다.

// 배열 정렬에 사용
['바나나', '사과', '포도'].sort((a, b) => a.localeCompare(b));
// 결과: ['바나나', '사과', '포도']

// 다른 언어 지원
'é'.localeCompare('f', 'fr'); // 프랑스어 기준으로 비교

배열 정렬에도 사용가능하다. Array.sort(a,b) => a.localeCompare(b)와 같이 정렬하고자 하는 배열의 sort/CompareFunction의 리턴값으로 활용할 수 있겠다.

profile
FrontEnd Developer

0개의 댓글