본문 바로가기
Developer/TIL

TIL : 250331월 (프로그래머스 해시, 윤년, 같은 숫자는 싫어, 문자열 내 마음대로 정렬하기(sort()함수에 대해 알아보기))

by 청량리 물냉면 2025. 3. 31.
반응형

프로그래머스 해시

function solution(nums) {
    var answer = {};
    nums.forEach((num, i) => {
        answer[num] ? answer[num]++ : answer[num] = 1;
    });
    
    return Math.min(nums.length/2, Object.keys(answer).length);
}

답지 안 보고 풀기는 했는데 성능면에서 문제가 좀 있는 것 같다. 

테스트케이스 아래쪽에 3-4s 걸리는 것도 있음...

nums가 최대 1만개까지 될 수 있기 때문에 시간복잡도는 O(N), 그리고 나머지는 O(1) 정도밖에 안 들것 같은데...

모범답안을 찾아보니 set이 있었다... 중복처리😂

추가로 찾아보니 `Object.keys(answer)`의 시간복잡도도 O(N)이었다.

`Object.keys(answer)`는 객체의 모든 키를 배열로 반환하는 함수이고, 이 과정에서 내부적으로 객체의 모든 키를 순회하면서 배열을 생성한다. 따라서 객체에 N개의 키가 있다면 O(N) 시간이 걸리게 된다.

 

 

2016년

function solution(a, b) {
    let dayOfWeek = ['SUN','MON','TUE','WED','THU','FRI','SAT'];
    let Month = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    let jinam = 0;
    
    for (let i = 0; i < a - 1; i++){
        jinam += Month[i];
    }
    jinam += b;
    
    let answer = ((jinam % 7) + 4) % 7;
    return dayOfWeek[answer];
}

요일을 찾기 위한 규칙을 찾는 게 너무 힘들었다ㅠㅠ

이 문제는 푸는 방법이 너무 다양해서 다른 풀이도 많이 참고해봐야 할듯. 시간 날 때마다 들여다 보자.

https://school.programmers.co.kr/learn/courses/30/lessons/12901/solution_groups?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

같은 숫자는 싫어

function solution(arr)
{
    var answer = [arr[0]];
    for(let i = 1; i < arr.length; i++) {
        if(answer[answer.length - 1] === arr[i]) continue;
        answer.push(arr[i]);
    }
    return answer;
}

모범답안에 filter를 이용한 풀이가 인상적이었다.

인덱스를 하나씩 올려가며 현재 수와 비교를 하는데, 마지막 answer[index+1]의 값은 참조에러가 나지 않을까?? 했는데...

해당 값은 undefiend가 되어서, 이전 값은 이 undefined 값과 비교하게 된다고 한다. 신기...

https://school.programmers.co.kr/learn/courses/30/lessons/12906/solution_groups?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

문자열 내 마음대로 정렬하기

function solution(strings, n) {
    strings.sort((a, b) => {
        return a[n] === b[n] ? a.localeCompare(b) : a[n].localeCompare(b[n]);
    })
    return strings;
}

정렬 함수 `sort()`에 대해 공부할 수 있었다.

파이썬에서는 람다를 이용해서 조건을 다양하게 걸어 정렬할 수 있는데, ` sort()`에 대해 잘만 알아두면 자바스크립트에서도 비슷하게 정렬을 구현할 수 있을 것 같다.

 

추가로, 위 코드의 전체적인 흐름 및 자세한 실행예제를 조금 살펴보기로 했다.

먼저 문제의 요구사항은 다음과 같다.

  • 문자열 배열 strings를 n번째 문자 기준으로 정렬
  • 만약 n번째 문자가 같은 경우, 전체 문자열을 사전순 정렬

 

📌 예제 1: 직접 실행하며 이해해보기

const arr = ["sun", "bed", "car"];
console.log(solution(arr, 1)); // ['car', 'bed', 'sun']

n = 1 이므로, 각 문자열의 인덱스 1번째 문자(실제로는 두 번째 문자)를 기준으로 비교한다.

문자열 1번째 문자 (n=1)
"sun" "u"
"bed" "e"
"car" "a"

 

🔹 비교 과정 (`sort()` 내부에서 실행됨)

1. 첫 번째 비교: "sun" vs "bed"

prev = "sun"; // 첫 번째 문자열
cur = "bed"; // 두 번째 문자열

 

기준 문자 비교

prev[n] = "sun"[1] = "u";
cur[n] = "bed"[1] = "e";
  • "u".localeCompare("e") → 양수 (1)
    • "e"가 "u"보다 먼저 와야 함 → "bed"가 "sun"보다 앞에 배치됨
    • (swap 발생)
  • 현재 정렬 상태: ["bed", "sun", "car"]

 

🏷 2. 두 번째 비교: "bed" vs "car"

prev = "bed";
cur = "car";

 

기준 문자 비교

prev[n] = "bed"[1] = "e";
cur[n] = "car"[1] = "a";
  • "e".localeCompare("a") → 양수 (1)
    • "a"가 "e"보다 먼저 와야 함 → "car"가 "bed"보다 앞에 배치됨
    • (swap 발생)
  • 현재 정렬 상태: ["car", "bed", "sun"]

 

📌 결과

최종적으로 n번째 문자를 기준으로 정렬된 결과

["car", "bed", "sun"]
  • "a" → "e" → "u" 순서대로 정렬

 

📌 예제 2: n번째 문자가 같은 경우

const arr2 = ["abc", "acd", "aaa"];
console.log(solution(arr2, 1)); // ['aaa', 'abc', 'acd']

 

각 문자열의 인덱스 1번째 문자(n=1) 비교

문자열 1번째 문자
"abc" "b"
"acd" "c"
"aaa" "a"
  1. "abc"[1] = "b", "acd"[1] = "c"
    • "b".localeCompare("c") → 음수 (-1) → 그대로 둠 (swap 없음)
  2. "abc"[1] = "b", "aaa"[1] = "a"
    • "b".localeCompare("a") → 양수 (1) → "aaa"가 앞으로 감 (swap 발생)
  3. "aaa"와 "abc"를 비교하면 전체 문자열 비교가 필요 없음. (a < b < c)

 

🔥 정리

정렬 방식
1️⃣ n번째 문자를 비교
2️⃣ 같으면 전체 문자열을 사전순 정렬
3️⃣ 다르면 n번째 문자 기준 정렬

 

왜 localeCompare()를 쓰는가?

  • prev[n].localeCompare(cur[n]): n번째 문자 기준 정렬
  • prev.localeCompare(cur): 같은 문자일 경우 전체 문자열 기준 사전순 정렬

 

 

`a.localeCompare(b)`의 동작 원리

`localeCompare()`는 문자열을 사전순으로 비교하는 JavaScript 내장 함수이다.
즉, "a", "b", "c" 같은 문자열을 알파벳 또는 한글, 숫자 등 정렬 기준에 맞춰 비교할 때 사용된다.

 

📌 기본 동작

console.log("apple".localeCompare("banana")); // -1
console.log("banana".localeCompare("apple")); // 1
console.log("apple".localeCompare("apple"));  // 0

✅ `a.localeCompare(b)`의 반환 값

  • 음수 (-1) → a가 b보다 먼저 와야 할 때
  • 양수 (1) → b가 a보다 먼저 와야 할 때
  • 0 → a와 b가 같을 때

🔍 어떻게 정렬 순서를 결정하는가?

  • 기본적으로 유니코드 코드 포인트 값을 기준으로 비교
  • 옵션을 사용하면 언어별 정렬 방식도 적용 가능

 

📌 예제 1: 기본 비교 (영어)

console.log("a".localeCompare("b"));  // -1 ("a"가 먼저)
console.log("b".localeCompare("a"));  // 1  ("b"가 나중)
console.log("b".localeCompare("b"));  // 0  (같음)

→ 알파벳 순서로 "a" < "b" < "c"가 되도록 비교.

 

📌 예제 2: 한글 비교

console.log("가".localeCompare("나")); // -1 ("가"가 먼저)
console.log("하".localeCompare("가")); // 1 ("하"가 나중)

→ "가"가 "나"보다 먼저 나오므로 -1 반환.

 

📌 예제 3: 대소문자 정렬

console.log("a".localeCompare("A"));  // 1 (기본적으로 소문자가 더 뒤)
console.log("A".localeCompare("a"));  // -1

→ 기본적으로 "A" < "a"이므로 "a".localeCompare("A")는 1을 반환.
대소문자를 무시하고 싶다면 옵션을 설정해야 함.

 

📌 예제 4: 숫자 포함된 문자열 정렬

const arr = ["item2", "item10", "item1"];
arr.sort((a, b) => a.localeCompare(b, "en", { numeric: true }));
console.log(arr); // ["item1", "item2", "item10"]

→ numeric: true 옵션을 사용하면 "item10"이 "item2"보다 뒤에 정렬됨.
(기본적으로 "item10"이 "item2"보다 먼저 오지만, 숫자 인식 시 정렬이 자연스럽게 됨.)

 

📌 옵션 활용

`localeCompare()`는 여러 가지 옵션을 제공함.

a.localeCompare(b, locale, options)
  • locale: "en"(영어), "ko"(한글), "fr"(프랑스어) 등 지정 가능.
  • options: 정렬 기준을 조정하는 객체.

주요 옵션

옵션 설명
sensitivity: "base" 대소문자 및 악센트 무시
numeric: true 숫자를 올바른 순서로 정렬
caseFirst: "upper" 대문자를 우선 정렬
console.log("a".localeCompare("A", "en", { sensitivity: "base" })); // 0 (대소문자 무시)
console.log("10".localeCompare("2", "en", { numeric: true })); // 1 ("2"가 "10"보다 먼저)
console.log("b".localeCompare("A", "en", { caseFirst: "upper" })); // 1 (대문자가 먼저)

 

 

 

 

`sort()`와` localeCompare()` 함수는 조금 더 자세히 공부하고, 예제를 여러번 적용하며 연습해봐야겠다.

반응형