[프로그래머스] 행렬의 곱셈 - 자바스크립트
https://programmers.co.kr/learn/courses/30/lessons/12949
코딩테스트 연습 - 행렬의 곱셈
[[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]]
programmers.co.kr
문제의 난이도가 어렵진 않다. 단지, 행렬의 계산이 어떻게 되는지를 머리로 잘그리고, 반복문에 수행되는 i, j, k 를 지정하는게 상당히 불편하다.
1. 사람마다 array를 만들면서, 문제를 푸는경우, 혹은 나처럼, 먼저 0을 넣어서 행렬의 모양을 만드는 풀이 두가지로 처음 풀이가 갈릴꺼 같다. (맨처음 for문을 사용한이유에 대한설명)
let num = arr1.length;
let num2 = arr2[0].length;
let list = [];
for (let i = 0 ; i<num;i++){
let l = []
for(let j=0; j<num2;j++){
l.push(0);
}
list.push(l)
}
2. 반복문이 3개 필요한 이유는 다음과 같다 행렬에는 2 * 3 행렬이 있으면 2 * 3의 행렬과 곱해야하는 행렬은 3 * x가 되야한다 그렇기에, x * y와 y * z 와 같이 이어주는 문자가 하나 필요하다.여기서는 y (행렬을 풀기 위한 선행지식)
3. 행렬을 곱은, 1 * 2 행렬과 2 *1의 행렬을 간단하게 곱해보면, list[0][0] = arr1[0][0] * arr2[0][0] + arr1[0][1] * arr2[1][0] 과 같다, 즉 list[i][j] = arr1[i][k]*arr2[k][j] + arr1[i][k]*arr2[k][j] 과 같은 모양이 나온다. 사실 i j 의 위치가 중요한게 아니라, 0 0 고정되있는 두개의 값과, 움지기는 유동의 값이 i j 사이에 들어가야 한다는 것을 인지하는게 중요하다.
for(let i=0;i<num;i++){
for(let j=0;j<arr2[0].length;j++){
for(let k =0; k<arr1[0].length;k++){
list[i][j] = arr1[i][k]*arr2[k][j]+list[i][j];
}
}
}
그리고 다음과 같이 만들면 (사실, 위으 풀이처럼 +를 누적해서 하지않고, k에대한 값을 sum으로 받아서 풀이하는 방법도 있다.
모든 풀이를 붙이면 다음과 같다.
function solution(arr1, arr2) {
let num = arr1.length;
let num2 = arr2[0].length;
let list = [];
for (let i = 0 ; i<num;i++){
let l = []
for(let j=0; j<num2;j++){
l.push(0);
}
list.push(l)
}
for(let i=0;i<num;i++){
for(let j=0;j<arr2[0].length;j++){
for(let k =0; k<arr1[0].length;k++){
list[i][j] = arr1[i][k]*arr2[k][j]+list[i][j];
}
}
}
return list;
}
문제를 풀때 하나씩 플로우 차트를 못하던 시절에는 상당히 귀찮았었...던 문제다 (지금 다시푸니까 그래도 쉽게 풀리는거지 이전엔 반복문을 어떻게 잡을지 못했었다). 플로우 차트를 작성하는 연습을 조금씩 늘리다보면 점점 좋아질꺼같다