728x90
📌 문제
https://school.programmers.co.kr/learn/courses/30/lessons/64065
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다.
- (a1, a2, a3, ..., an)
튜플은 다음과 같은 성질을 가지고 있습니다.
- 중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)
- 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2)
- 튜플의 원소 개수는 유한합니다.
원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다.
- {{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4, ..., an}}
예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는
- {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}
와 같이 표현할 수 있습니다. 이때, 집합은 원소의 순서가 바뀌어도 상관없으므로
- {{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}
- {{2, 1, 3, 4}, {2}, {2, 1, 3}, {2, 1}}
- {{1, 2, 3}, {2, 1}, {1, 2, 4, 3}, {2}}
는 모두 같은 튜플 (2, 1, 3, 4)를 나타냅니다.
특정 튜플을 표현하는 집합이 담긴 문자열 s가 매개변수로 주어질 때, s가 표현하는 튜플을 배열에 담아 return 하도록 solution 함수를 완성해주세요.
📌 제한사항
- s의 길이는 5 이상 1,000,000 이하입니다.숫자가 0으로 시작하는 경우는 없습니다.
- s가 표현하는 튜플의 원소는 1 이상 100,000 이하인 자연수입니다.
- return 하는 배열의 길이가 1 이상 500 이하인 경우만 입력으로 주어집니다.
- s는 항상 중복되는 원소가 없는 튜플을 올바르게 표현하고 있습니다.
- s는 숫자와 '{', '}', ',' 로만 이루어져 있습니다.
📌 입출력 예
📌 풀이
알아야 하는 것
- replaceAll (정규표현식)
- split
- map
- forEach
- sort
- array.from
- 구조 분해 할당
문제 풀이
- 예제 2번을 보고 문제를 잘 이해 못했는데 다른 분들의 힌트로 문제를 이해할 수 있게 됐다.
- return할 배열 answer를 선언하고 처음 들어오는 입력값의 형태를 number로 바꿔준다.
- 이 과정에서 정규표현식, split, map을 사용했다.
- map을 선언하고 이 안에 k, v로 키값과 빈도수를 넣어줬다.
- map 객체로 만들었기 때문에 좀 더 쉽게 접근하기 위해 배열로 만들려고 forEach를 돌았다.
- 이 때 키랑 빈도수가 반대로 들어가기 때문에 push할 때 v, i로 넣어주고 빈도수가 높은 순으로 정렬한다.
- 답을 return할 배열 answer에 빈도수가 높은 순으로 정렬된 배열의 키값을 넣어준다.
- 한 눈에 봐도 코드가 매우 비효율적으로 보인다.
function solution(s) {
let pair = [];
let num = s
.replaceAll('{', '')
.replaceAll('}', '')
.split(',')
.map((v) => Number(v));
let map = new Map();
for (let i = 0; i < num.length; i++) {
map.set(num[i], (map.get(num[i]) || 0) + 1);
}
let pairs = map.forEach((i, v) => {
pair.push([v, i]);
});
pair.sort((a, b) => b[1] - a[1]);
let answer = [];
for (let i = 0; i < pair.length; i++) {
answer.push(pair[i][0]);
}
return answer;
}
2번째 코드
function solution(s) {
const num = s.replace(/{|}/g, '').split(',').map(Number);
const map = new Map();
num.forEach((v) => map.set(v, (map.get(v) || 0) + 1));
const sortedPairs = Array.from(map).sort((a, b) => b[1] - a[1]);
const answer = sortedPairs.map(([key]) => key);
return answer;
}
- 입력값을 가공하는 부분을 한 줄로 좀 더 간략하게 할 수 있다.
- 아까는 replaceAll을 2번 썼는데, 그럴 필요 없이 replace와 |를 사용해서 {거나 }면 ''으로 바꾸게 하면 된다.
- 여기에 바로 split이랑 map을 써주면 코드가 더 짧아진다.
- 나처럼 정규표현식에 익숙하지 않은 사람은 1번이 좀 더 이해하기 쉬울지도 모르겠지만...?
- map이랑 forEach를 합쳐서 더 짧게 쓸 수 있다.
- num에 forEach, map을 써서 순회하면서 map 객체를 한번에 만들 수 있다.
- 만든 map 객체를 일반 배열로 만들기 위해 Array.from을 사용한다.
- 이후 빈도수가 높은 순으로 정렬하고, map으로 해당 배열을 순회하면서 구조 분해 할당으로 키를 가져온다.
- 이 부분 문법이 잘 이해가 안됐는데, sortedPairs = [ [ 2, 4 ], [ 1, 3 ], [ 3, 2 ], [ 4, 1 ] ] 일 때, [key, value]라고 해버리면 key만 가져올 수가 있다. 구조 분해 할당으로 2 = key, 1 = key, 3 = key... 이런 식으로 key에 접근해서 가져온 후 return하면 된다.
728x90
'⚙️ 코딩테스트' 카테고리의 다른 글
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 뉴스 클러스터링 (1) | 2023.12.28 |
---|---|
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 귤 고르기 (1) | 2023.10.31 |
[JavaScript] 프로그래머스 코딩테스트 레벨 1 : 성격 유형 검사하기 (2) | 2023.10.30 |
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 괄호 회전하기 (1) | 2023.10.19 |
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 영어 끝말잇기 (0) | 2023.10.17 |