공부/코딩

[프로그래머스/연습문제] 행렬의 곱셈

하루김이박 2025. 1. 4. 16:18
반응형

오늘의 문제는 <행렬의 곱셈>인데요.
(문제 출처 : 프로그래머스 https://school.programmers.co.kr/learn/courses/30/lessons/12949)

프로그래머스는 블로그 게재시 문제 여지가 있어
자세한 내용 없이 문제 제목과 링크로 대체합니다. 

벌써부터 막혀서 힌트 오조오억번 봤다죠,,ㅠㅠ
이번 문제는 그래서 나중에 다시 풀어볼 예정입니다

행렬의 곱셈은 그냥 손으로 풀면 쉬운데요.
결과 행렬 (i,j)의 성분은 A 행렬 i 행의 값과 B 행렬 j 행의 값을 차례대로 곱하면서 더한 것과 같아요.

예를 들어 행렬 하나를 만들어 예시로 보면
  arr1                                                         arr2                                                               return
[[1, 4], [3, 2], [4, 1]]                                    [[3, 3], [3, 3]]                                    [[15, 15], [15, 15], [15, 15]]

사실은 이렇게 생긴 행렬들이고,
arr1                                                         arr2                                                               return
[[1, 4]                                                       [[3, 3]                                                           [[15, 15]  
[3, 2]                                                        [3, 3]]                                                           ,[15, 15]
[4, 1]]                                                                                                                            ,[15, 15]]

파랑색으로 표시한 return 배열의 151*3 + 4*3 의 결과에요.
arr1                                                         arr2                                                               return
[[1, 4]                                                        [[3, 3]                                                           [[15, 15]  
[3, 2]                                                        [3, 3]]                                                           ,[15, 15]
[4, 1]]                                                                                                                            ,[15, 15]]

이렇게 순서대로 더해 나가는거죠!

출처 : 수학방(mathbang.net/562)

이걸 조금 더 고급지게 정리해보자면
A 행렬의 크기가 (m * k), B 행렬의 크기가 (k * n) 일 때
두 행렬의 곱 연산 결과는 m * n 이 됩니다.
A의 행의 개수 k와 B의 열의 개수 k를 기준으로 곱하기 때문이에요.
그래서 k는 똑같아야 해요.
이번 문제에서는 곱할 수 있는 배열만 주어진다는 조건을 걸어
k가 똑같다는 걸 알려줬는데요.
만약 이런 조건이 없다면 두 k를 비교해 곱하기가 가능한지 고려하는 연산도 추가해야 합니다.

다시 문제로 돌아와서

class Solution {
    public int[][] solution(int[][] arr1, int[][] arr2) {
        int r1 = arr1.length;
        int c1 = arr1[0].length; // arr1의 행과 열 계산 c1 = k
        
        int r2 = arr2.length; // c1 = r2 = k
        int c2 = arr2[0].length; // arr2의 행과 열 계산
        
        // 결과 행렬 크기는 앞쪽 행렬의 행(r1) * 뒷쪽 행렬의 열(c2)
        int[][] answer = new int[r1][c2];
        
        for (int i=0; i<r1; i++){ // arr1의 각 행
            for (int j=0; j<c2; j++){ // arr2의 각 열을 반복하는데
                
                for(int k=0; k<c1; k++){
                	// 두 행렬의 데이터를 곱해야 하는데 k가 반복되어야 함
                   answer[i][j] += arr1[i][k] * arr2[k][j];
                    // [0][0] = [0][0] * [0][0]
                    // [0][0] = [0][1] * [1][0]
                    // [0][1] = [0][0] * [0][1]
                    // [0][1] = [0][1] * [1][1]
                }
            }
        }
        return answer;
    }
}

수학적 사고력이 없는
과거의 수포자 인간이라 힘들었따^^
이 문제는 무조건 나중에 다시 풀어봐야지

 

반응형