📍 행렬의 곱셈
2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.
단순히 arr1[i][j]
와 arr2[i][j]
를 곱하면 되는 줄 알았는데 아니었다. 행렬을 곱하는 방법이 따로 있다고 한다.
A 행렬(파란색)과 B 행렬(초록색)의 곱셈을 그림으로 설명하면 이런데.. 말로 설명하자면, A 행렬의 (0, 0)과 B 행렬의 (0, 0)을 곱한 값을 a라고 하고, A 행렬의 (0, 1)과 B 행렬의 (1, 0)을 곱합 값을 b라고 했을 때, A와 B의 행렬을 곱한 배열의 (0, 0)의 값은 a와 b를 더한 값과 같다.
즉, 결과는 A 행렬의 행 개수 * B 행렬의 열 개수
만큼의 크기를 지니게 된다.
공식 그대로 풀었다. arr1은 행은 고정된 채로 열의 값만 늘어나고, arr2는 열은 고정된 채로 행의 값만 늘어난다. 각각의 요소들을 곱한 값들을 fold를 사용해 더해주었다.
class Solution {
fun solution(arr1: Array<IntArray>, arr2: Array<IntArray>): Array<IntArray> {
// i는 행, j는 열
return arr1.indices.map { i ->
arr2[0].indices.map { j ->
// arr1의 행은 고정된다.
// 순회하게 되면 별도의 인덱스 지정 없이 행은 고정된 채로 열의 값만 바뀐 요소들이 v에 들어온다.
// idx는 열의 번호!
arr1[i].foldIndexed(0) { idx, total, v ->
total + v * arr2[idx][j]
}
}.toIntArray()
}.toTypedArray()
}
}
나는 각 행을 나타내는 배열을 IntArray로 바꿔주고, 전체 배열을 또 Array로 바꿔주었는데, 아예 배열 초기화를 사용해 형변환 없이 푼 사람이 있었다.
class Solution {
fun solution(arr1: Array<IntArray>, arr2: Array<IntArray>): Array<IntArray> {
var answer = Array<IntArray>(arr1.size) { i ->
Array<Int>(arr2[0].size) { j ->
var value = 0
for(n in 0 until arr1[i].size) {
value += (arr1[i][n] * arr2[n][j])
}
value
}.toIntArray()
}
return answer
}
}
행렬의 곱셈 방식을 알아보는 데 시간이 좀 걸렸다. 수학 공부 좀 열심히 할 걸 그랬다. 오늘 알게되었으니까 다음에 또 나오면 잘 풀 수 있겠지?