백준 10810번을 풀고 기존 풀이를 개선할 수 있는 부분이 있어 정리해보고자 한다.
let [NM, ...input] = require('fs').readFileSync('/dev/stdin').toString().split('\n')
const N = NM.split(' ').map(Number)[0]
const M = NM.split(' ').map(Number)[1]
let basket = []
for (let i = 0; i < N; i++) {
basket.push(0)
}
for (let i = 0; i < M; i++) {
const m = input[i].split(' ').map(Number)
const start = m[0], end = m[1], n = m[2]
for (let j = start - 1; j < end; j++) {
basket[j] = n
}
}
console.log(basket.join(' '))
1. Array 객체의 fill 메소드
// let basket = []
// for (let i = 0; i < N; i++) {
// basket.push(0)
// }
let basket = new Array(N).fill(0)
basket 배열에 0을 채우기 위해 반복문을 사용하였는데 fill 메소드를 사용하면 한 줄로 처리할 수 있다.
2. 다중 할당
// const m = input[i].split(' ').map(Number)
// const start = m[0], end = m[1], n = m[2]
const [start, end, n] = input[i].split(' ').map(Number)
시작 바구니 번호, 끝 바구니 번호, 공 번호를 얻기 위해 임시로 m을 선언한 후 start, end, n에 각각 할당해주었는데
다중 할당을 사용하면 한 줄로 처리할 수 있다.
1, 2번을 적용하면 아래의 코드가 완성된다.
let [NM, ...input] = require('fs').readFileSync('/dev/stdin').toString().split('\n')
const N = NM.split(' ').map(Number)[0]
const M = NM.split(' ').map(Number)[1]
let basket = new Array(N).fill(0)
for (let i = 0; i < M; i++) {
const [start, end, n] = input[i].split(' ').map(Number)
for (let j = start - 1; j < end; j++) {
basket[j] = n
}
}
console.log(basket.join(' '))
그러나 아래의 3, 4번을 적용하면 더 짧은 풀이도 가능하다.
3. 다중 할당 ① 다중 할당 내 다중 할당
// let [NM, ...input] = require('fs').readFileSync('example.txt').toString().split('\n')
// const N = NM.split(' ').map(Number)[0]
// const M = NM.split(' ').map(Number)[1]
let [[N, M], ...input] = require('fs').readFileSync('example.txt').toString().split('\n').map(x => x.split(' ').map(Number))
기존의 방식으로 입력값을 받을 경우,
NM은 '5 4', input은 ['1 2 3', '3 4 4', '1 4 1', '2 2 2']를 가지므로
NM.split(' ').map(Number) 후 각각을 N, M으로 지정하고
input[i].split(' ').map(Number) 후 각각을 start, end, n로 지정해야 했다.
그러나 [NM, ...input]을 [[N, M], ...input]으로 수정해 다중 할당 내 다중 할당이 가능하도록 하고
require('fs').readFileSync('example.txt').toString().split('\n').map(x => x.split(' ').map(Number))로 수정하면
N은 5, M은 4, input은 [[1, 2, 3], [3, 4, 4], [1, 4, 1], [2, 2, 2]]을 가지므로
추가적인 작업 없이 한 번에 정제된 N, M, input 값을 얻을 수 있게 된다.
4. 다중 할당 ②
// for (let i = 0; i < M; i++) {
// const [start, end, n] = input[i].split(' ').map(Number)
// for (let j = start - 1; j < end; j++) {
// basket[j] = n
// }
// }
for (let [i, j, k] of input) {
for (let index = i - 1; index < j; index++) {
basket[index] = k
}
}
위 코드를 분석해보기 전, 먼저 비구조화 할당에 대해 알아보자.
객체 ③ 객체와 배열 고급에서 배열 기반의 다중 할당, 객체 기반의 다중 할당을 배운 후 다중 할당이라는 용어를 줄곧 써왔는데,
알고보니 다중 할당의 상위 개념으로 비구조화 할당(구조 분해 할당)이 있었다.
비구조화 할당, 구조 분해 할당은 배열이나 객체를 분해하여 그 값을 개별 변수에 담을 수 있게 하는 표현식으로,
다중 할당이란 용어는 비구조화 할당 중에서도 배열과 객체 하나로 여러 변수에 값을 할당할 수 있다는 점을 특히 강조하기 위해 쓰이는 것 같다.
이제 본론으로 돌아와 위 코드를 분석해보자.
위 코드의 경우 반복문의 조건을 let [i, j, k] of input으로 비구조화 할당을 사용하여 굳이 start, end, n을 정의할 필요가 없어졌다.
3, 4번을 적용해 완성된 최종 코드는 아래와 같다.
let [[N, M], ...input] = require('fs').readFileSync('example.txt').toString().split('\n').map(x => x.split(' ').map(Number))
let basket = new Array(N).fill(0)
for (let [i, j, k] of input) {
for (let index = i - 1; index < j; index++) {
basket[index] = k
}
}
console.log(basket.join(' '))
위에서 배운 내용은 유사한 유형인 백준 10813번에도 적용할 수 있다.
let [[N, M], ...input] = require('fs').readFileSync('/dev/stdin').toString().split('\n').map(x => x.split(' ').map(Number))
let basket = []
for (let i = 0; i < N; i++) {
basket.push(i+1)
}
for (const [i, j] of input) {
const tmp = basket[i-1]
basket[i-1] = basket[j-1]
basket[j-1] = tmp
}
console.log(basket.join(' '))
💫 이 문제를 통해 배운 것
• 다중 할당 내에서 또 다중 할당을 할 수 있다.
• 배열을 반복할 때 반복문의 조건으로 비구조화 할당을 사용할 수 있다.