[LV1] 행렬의 덧셈
사람들이 lv0을 건너뛰고 lv1부터 시작하는지 lv1 문제에는 질문글이 엄청나게 많았다. lv0 안풀고 왔으면 이걸 손도 못댔겄지...
행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.
제한 조건- 행렬 arr1, arr2의 행과 열의 길이는 500을 넘지 않습니다.
arr1 | arr2 | return |
[[1,2],[2,3]] | [[3,4],[5,6]] | [[4,6],[7,9]] |
[[1],[2]] | [[3],[4]] | [[4],[6]] |
흔한 행렬의 덧셈 문제였다. 문제는 2차원 행렬이었다는 것...!
일차원 행렬의 덧셈이나, 두 행렬의 덧셈 같은 경우에는 reduce() 함수를 이용해서 문제를 풀 수 있었겠지만, 이차원 행렬의 덧셈은 처음 만나보는 타입이라서 리자몽을 마주친 지우처럼 니용? 하고 있었다. 포켓몬스터 안봄
- 각 배열 요소들의 합을 하나의 일차원 배열에 저장
- 일차원 배열을 간격별로 slice하여 answer 배열에 push
다음과 같은 메커니즘을 사용하였다.
관건은 for문의 간격 조정과 slice의 범위 지정. 주어진 배열과 같은 모양으로 만들어 주어야 했기 때문에 굉장히 신경쓸 것들이 많았다.
먼저 두 이차원 행렬의 요소들을 더하여 새로운 일차원 배열을 만들어 주었다.
이중 for문을 사용하였으며, 빈 배열 arr를 만들어 두 요소의 값을 push 하는 방식을 사용하였다.
let arr = []
for(let i = 0; i < arr1.length; i++){
for(let j = 0; j < arr1[0].length; j++){
arr.push((arr1[i][j] + arr2[i][j]))
}
}
코드블럭이라는게 있는지 처음 알았다. 오우오우
아무튼, 이 과정을 거칠 경우 arr에는 1행 1열의 합, 1행 2열의 합, ... n행 m열의 합이 요소로 저장되어 있을 것이다.
위의 예시 1번의 경우에는 arr = [4, 6, 7, 9]
이제 이 arr 배열을 다시 주어진 조건에 맞게 2차원 배열로 만들어주어야 한다.
긴 1차원 배열을 부분부분 잘라서 새로운 배열을 만드는데는 slice() 함수가 가장 적절하다고 판단했다.
slice의 범위는 '열의 길이'만큼. 4x5 배열이라면 slice(i. i+5)만큼 실시하면 된다는 것이다.
slice를 한번만 할 수는 없으니 for문을 사용하기로 했다.
그런데 여기서 잠깐!
우리가 평소에 사용하던 for문의 조건은
for(let i = 0; i < n; i++)
i가 주어진 수까지 1씩 증가하는 방식이었다. 하지만 우리는 slice() 함수를 arr1, arr2 배열의 '행의 길이'만큼만 실행해 주어야 한다. 그러기 위해서는 맨 뒤의 i++, 즉 i의 증가량을 수정해 주어야 한다.
arr = [4, 6, 7, 9]에서, slice를 실행하면 [4, 6]과 [7, 9]라는 2개의 배열로 나뉘는데, 이때 각 배열의 요소의 개수는 열의 길이와 같다. 그렇다면 배열의 첫 요소의 인덱스는 (이전 배열의 첫 요소의 인덱스 +열의 길이)가 된다.
한마디로 반복문에서 i의 증가량은 '열의 길이'가 되어야 한다는 말이다.
그러므로 증가량을 i++이 아니라, i+=열의 길이로 수정해야 한다.
행의 길이는 arr1.length, 열의 길이는 arr1[0].length이다. 이를 모두 사용하여 for문을 만들면
for(let i = 0; i < arr.length; i+=arr1[0].length){
answer.push(arr.slice(i, i+arr1[0].length))
}
범위는 arr의 길이, 증가량은 열의 길이, 그리고 slice()의 범위 역시 i부터 열의 길이만큼만 자르게 된다. 그리고 이 자른 배열은 1차원 배열이므로, 빈 배열 answer에 push 해주면 자연스럽게 2차원 배열이 만들어진다.
function solution(arr1, arr2) {
var answer = []
let arr = []
for(let i = 0; i < arr1.length; i++){
for(let j = 0; j < arr1[0].length; j++){
arr.push((arr1[i][j] + arr2[i][j]))
}
}
for(let i = 0; i < arr.length; i+=arr1[0].length){
answer.push(arr.slice(i, i+arr1[0].length))
}
return answer
}
for문은 메모리와 런타임이 좀 들어서 배열을 다루는 함수들을 좀더 중점적으로 공부해 봐야겠다는 생각이 들었다.