2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.
arr1 | arr2 | return |
---|---|---|
[[1, 4], [3, 2], [4, 1]] | [[3, 3], [3, 3]] | [[15, 15], [15, 15], [15, 15]] |
[[2, 3, 2], [4, 2, 4], [3, 1, 4]] | [[5, 4, 3], [2, 4, 1], [3, 1, 1]] | [[22, 22, 11], [36, 28, 18], [29, 20, 14]] |
function solution(arr1, arr2) {
const newArr = [];
for(let i = 0; i < arr1.length; i++) {
let result = [];
for(let j = 0; j < arr2[0].length; j++) {
let elem = 0;
for(let k = 0; k < arr2.length; k++) { // arr1[0].length도 가능.
elem += arr1[i][k] * arr2[k][j];
}
result.push(elem);
}
newArr.push(result);
}
return newArr;
}
일단 이 문제는 행렬의 곱셈을 하는 방법에 대해 알아야 풀 수 있습니다.
행렬을 곱하는 방법은 Wikipedia에 자세히 나와있습니다.
행렬의 곱셈을 통해 우리가 결과값의 인덱스 0, 0의 값을 구하려고 한다면
앞의 0은 arr1의 0행 전부, 뒤의 0은 arr2의 0열 전부를 순서대로 곱한 후 더한 값과 같습니다.
result[0, 0] = ( arr1[0, 0] * arr2[0, 0] ) + ( arr1[0, 1] * arr2[1, 0] ) + ( arr1[0, 2] * arr2[2, 0] )
행렬의 곱셈을 하기 위해서는 B와 C가 같을 때만 가능하고 곱셈에 대한 결과값은 A*D입니다.
설명에서 곱할 수 있는 배열만 주어진다고 했으므로 B와 C가 같은지는 판단하지 않아도 됩니다.
이 문제는 for 3중문을 통해서 풀 수 있으며 각 반복문에 i, j, k를 대입합니다.
for문이 3개나 연속해서 들어가다보니 i, j, k의 각 역할과 반복횟수가 헷갈릴 수 있는데
가장 바깥쪽 반복문의 i는 A (= arr1.length)와 같습니다.
j는 result의 열의 개수이며 D (=arr2[0].length)와 같습니다.
k는 result의 한 칸의 값을 구하기 위해 실제 반복해야하는 수로 B와 C에 해당합니다
(arr1[0].length || arr2.length).
여기서 중요한건 k의 반복문에서 arr1과 arr2의 각 칸을 곱한값을 구하고 이 값을 더해서 임시로 저장할 변수가 필요합니다.
그래서 이 변수를 j가 있는 반복문 시작시에 선언하여 k반복문이 끝날 때마다 이 변수에 +=
을 통해 더한 값을 저장해주어야 합니다. 답안에서의 elem
변수가 이 역할을 합니다.
k의 반복문이 끝나면 result의 칸에 들어갈 값을 elem
변수가 가지게 되므로 리턴 할 배열에 push를 해주면 됩니다.
결과값은 2차원 배열이므로 i의 반복문이 끝날때마다 결과값에 push를 해줍니다.