📝 문제
2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.
- 제한 조건
- 행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.
- 행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.
- 곱할 수 있는 배열만 주어집니다.
🔑 행렬의 곱셈
예시로 A, B 두 개의 행렬을 가져왔다.
A는 2x3 행렬, B는 3x2 행렬이다.
행렬의 곱셈은 아래와 같이 진행된다.
이것은 행렬 AB의 (1,1) 성분을 구하는 과정이다.
a의 1행 1열 값은 b의 1행 1열 값과 곱해주고, 이어서 a의 1행 2열 값은 b의 2행 1열 값과 곱해준다.
a의 1행 3열 값은 b의 3행 1열 값과 곱해주고 이를 모두 더해준다.
이 모든 과정을 거쳐 결과값은 2x2 형태의 행렬이 된다.
그러므로 곱셈을 위해서는 A와 열과 B의 행의 갯수는 같아야 한다.
결과값의 행열은 아래와 같다.
A (m × k) x B (k × n) = AB (m x n)
이제 행렬의 곱셈을 알았으니 코드로 구현해보자.
📝 구현
자바스크립트로 구현된 행렬은 2차원 배열이다.
각 요소가 한 행이고, 열은 각 행의 동일한 인덱스이다.
그러므로 이를 순회하기 위해 반복문은 필수적이다.
다만 단순히 한 행을 순회하는 것이 아니라,
B를 순회할 때는 한 열을 순회해야하기 때문에 반복문을 여러 번 중복해야 한다.
그림 보면서 코드를 보면 이해가 더 쉬워서 한 번 더 가져왔다.
function solution(A, B) {
let answer = [];
for (let i = 0; i < A.length; i++) { // A의 행 순회
answer.push([]); // A.length(행) => answer.length(행) 이므로 여기서 추가
let arr = A[i]; // 계산할 A의 요소(배열) 고정
for(let j = 0; j < B[0].length; j++) { // B의 열 순회
let sum = 0;
for(let k = 0; k < B.length; k++) { // B의 행 순회
sum += arr[k] * B[k][j]; // A는 행 고정-열 순회 / B는 행 순회-열 고정
}
answer[i].push(sum); // 배열에 값 추가
}
}
return answer;
}
위에 A[i]
를 고정하지 않는다면 아래와 같다.
function solution(A, B) {
let answer = [];
for (let i = 0; i < A.length; i++) { // A의 행 순회
answer.push([]); // A.length(행) => answer.length(행) 이므로 여기서 추가
for(let j = 0; j < B[0].length; j++) { // B의 열 순회
let sum = 0;
for(let k = 0; k < B.length; k++) { // B의 행 순회
sum += A[i][k] * B[k][j]; // A는 행 고정-열 순회 / B는 행 순회-열 고정
}
answer[i].push(sum); // 배열에 값 추가
}
}
return answer;
}
차근차근 여러 번 보면서 익히는 수 밖에 없는 것 같다.
- 정확도 테스트 결과
2차 풀이 (모범 풀이)
function solution(arr1, arr2) {
// arr1 = m x k , arr2 = k x n, answer = m x n
// 각 값은 arr1[i][0] x arr2[0][i] + ... k까지 더한 값
let m = arr1.length;
let k = arr1[0].length;
let n = arr2[0].length
// answer의 빈공간 만들기
let answer = Array.from({length: m}, () => new Array(n).fill(0));
// answer 순회하며 값 채워넣음
return answer.map((arr, idx) => {
return arr.map((v,index) => {
let value = 0;
for(let i = 0; i < k; i++) {
value += arr1[idx][i] * arr2[i][index];
}
return value;
})
})
}
- 정확도 테스트 결과
참고
https://mathbang.net/
habitual-history.tistory.com/t
'Coding test' 카테고리의 다른 글
[프로그래머스] n개의 최소공배수 (Lv 2) - javascript (0) | 2022.05.23 |
---|---|
[프로그래머스] JadenCase 문자열 만들기 (Lv 2) - javascript (0) | 2022.05.21 |
[프로그래머스] 최솟값 만들기 (Lv 2) - javascript (0) | 2022.05.19 |
[프로그래머스] 최댓값과 최솟값 (Lv 2) - javascript (0) | 2022.05.19 |
[프로그래머스] 숫자의 표현 (Lv 2) - javascript (0) | 2022.05.19 |