난이도: Lv. 2
정답률: 56%
문제: https://school.programmers.co.kr/learn/courses/30/lessons/17686
알고리즘
1. 각 파일명에서 head 부분과 number 부분을 객체로 저장한다. 객체로 저장할 때 origin이라는 키로 원래의 파일 이름도 저장한다.
2. 1.의 과정을 반복하며 키를 head 부분, value를 1.에서 생성한 객체들을 저장한 배열로 하는 객체를 만든다.
3. 2.에서 생성한 객체를 [key, value]의 배열로 변환한다.
4. 3.에서 생성한 배열의 0번째 원소는 모두 대문자로 변환된 head이고, 첫 번째 원소는 해당하는 head를 가지는 객체들을 담은 배열이다. 따라서 먼저 0번째 원소로 정렬하고, 첫 번째 원소인 배열 내부를 정렬한다.
5. 정렬을 마친 4.의 배열에서 원래의 파일 이름을 가지고 있는 origin을 정답 배열에 담는다.
코드
function solution(files) {
var answer = [];
const headKeyObj = {};
const objArr = [];
for (let file of files) {
const fileObj = { head: '', number: '' };
fileObj['origin'] = file;
for (let i = 0; i < file.length; i++) {
if (file[i] >= '0' && file[i] <= '9') {
fileObj['number'] += file[i];
if (i !== file.length - 1 && (file[i + 1] < '0' || file[i + 1] > '9')) { break; }
} else { fileObj['head'] += file[i].toUpperCase(); }
}
if (headKeyObj[fileObj['head']]) {
headKeyObj[fileObj['head']].push({ number: Number(fileObj['number']), origin: fileObj['origin'] });
} else {
headKeyObj[fileObj['head']] = [{ number: Number(fileObj['number']), origin: fileObj['origin'] }];
}
}
for (let [key, value] of Object.entries(headKeyObj)) {
objArr.push([key, value]);
}
objArr.sort((a, b) => {
if (a[0] < b[0]) { return -1; }
else if (a[0] > b[0]) { return 1; }
})
for (let i = 0; i < objArr.length; i++) {
objArr[i][1].sort((a, b) => a['number'] - b['number']);
}
for (let head of objArr) {
for (let value of head[1]) {
answer.push(value['origin']);
}
}
return answer;
}
주저리
아무리 반례를 넣어봐도 다 제대로 동작하는데 왜 안되는지 머리 쥐어뜯다가 질문하기에서 정렬을 제대로 알고 있는지 다시 확인해 보라길래 그냥 혹시나 하는 마음에 정렬 부분 좀 고쳐봤는데 통과했다.
objArr.sort((a, b) => a[0] - b[0] ? 1 : -1);
objArr.sort((a, b) => {
if (a[0] < b[0]) { return -1; }
else if (a[0] > b[0]) { return 1; }
})
위에 코드를 아래와 같이 바꾸니까 통과됐다.
objArr.sort((a, b) => a[0] < b[0] ? -1 : 1);
이거 처럼 더 간단하게 쓸 수도 있다.
첫 번째 코드가 실패한 이유는 두 문자열이 같을 때는 바꾸지 않아야 하는데 바꿔서 그런 건 줄 알았는데 근데 밑에 코드가 또 안되길래 무언가 잘못됨을 깨달았다.
objArr.sort((a, b) => a[0] - b[0] < 0 ? -1 : 1);
근데 진짜 왜 그런건지 깨달았다. 문자열끼리는 뺄 수 없기 때문이다. 중간 과정을 출력해 보면 NaN이 나온다.
참고로 리턴값이 -1이면 바꾸지 않고 1이면 바꾼다.
진짜 주저리지만 방금 프로그래머스 닫다가 아무생각 없이 티스토리도 닫아서 글 날아간 줄 알고 식겁했다.
'코딩테스트' 카테고리의 다른 글
[JS] 숫자 변환하기 (0) | 2024.01.18 |
---|---|
[JS] 프렌즈4블록 (0) | 2024.01.17 |
[JS] 롤케이크 자르기 (0) | 2024.01.12 |
[JS] 오픈채팅방 (0) | 2024.01.11 |
[JS] 스킬트리 (0) | 2024.01.10 |