[프로그래머스] 행렬의 곱셈 - JavaScript

coderH·2022년 2월 23일
4

프로그래머스코테

목록 보기
4/27
post-thumbnail

행렬의 곱셈

문제

2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.

  • 행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.
  • 행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.
  • 곱할 수 있는 배열만 주어집니다.

입출력

arr1arr2return
[[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를 해줍니다.

0개의 댓글