코테 노트/프로그래머스

Level 2 행렬의 곱셈 Python3

화요밍 2021. 1. 8. 19:52
728x90
반응형

 

https://programmers.co.kr/learn/courses/30/lessons/12949?language=python3

 

코딩테스트 연습 - 행렬의 곱셈

[[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

 

최종 코드

def solution(arr1, arr2):
    answer = [[0] * len(arr2[0]) for row in range(len(arr1))]
    for row in range(len(arr1)):
        for col in range(len(arr2[0])):
            sum = 0
            for i in range(len(arr1[0])):
                sum += (arr1[row][i] * arr2[i][col])
            answer[row][col] = sum
    return answer

풀이 과정

풀이 시간 41분

 

1. 행렬 곱 이해하기

[그림 1]

 [그림 1]처럼, 행렬의 행은 가로 방향, 열은 세로 방향이다.

A행렬 x B행렬의 결과인 AB의 행은 A의 행, 즉 m과 같고 열은 B의 열과 같다.

[그림 2]

 예를 들어 [그림 2]처럼, 왼쪽 그림과 같은 경우, c행렬의 행은 a의 3행, 열은 b열의 2열로 3x2 행렬이 된다.

 

 

2. 정답 행렬 초기화

 이에 따라, 정답 행렬인 answer을 초기화 해준다. 

answer = [[0] * len(arr2[0]) for row in range(len(arr1))]

arr1 x arr2 = answer이므로, arr1의 행 = len(arr1), arr2의 열 = len(arr2[0])으로 구해 값을 0으로 초기화하는 리스트를 만든다.

위의 그림의 경우, 각 row에 [0, 0]이 발생하여 answer = [[0, 0], [0, 0], [0, 0]]이 된다.

 

 

3. 행렬곱 3중 for문 설계

for row in range(len(arr1)):
    for col in range(len(arr2[0])):
        sum = 0
        for i in range(len(arr1[0])):
            sum += (arr1[row][i] * arr2[i][col])
        answer[row][col] = sum

 위의 예시를 보고, 행렬곱이 이뤄지는 규칙을 찾아 for문을 설계한다.

answer의 각 행 안에서 2개의 열 값이 필요하기 때문에 맨 바깥 for문은 arr1의 행으로, 그 안의 for문은 arr2의 열 값으로 반복한다.

이제 각 행렬 값을 구해줘야 하는데, a(row,i) x b(i,col)의 합이라는 규칙을 찾을 수 있다. 이 때, k는 arr1의 열 또는 arr2의 행과 같다.

이렇게 i번의 곱을 더해준 sum값이 answer(row,col)의 행렬 값이 된다.

 

 


다른 사람의 풀이 분석

def productMatrix(A, B):
    return [[sum(a*b for a, b in zip(A_row,B_col)) for B_col in zip(*B)] for A_row in A]

 zip을 활용하여 3중 for문을 한 줄로 짠 코드이다.

내장 함수 zip에 대해 잘 모르겠다면 글 아래 참고 부분에 정리해놓은 포스트를 참고하면 된다.

 

예시

A = [[1, 2], [3, 4], [5, 6]]
B = [[2, 4], [1, 2]]

[그림 3]

 [그림 3]처럼, 풀어가면 된다. 

 먼저, A_row = [1, 2] 일 때,

    - zip(*B)

         * = unpack

       1. B_col = [2, 1]

            - zip(A_row, B_col) = zip([1, 2], [2, 1])

                1 - 1. a = 1, b = 2 -> a*b = 2

                1 - 2. a = 2, b = 1 -> a*b = 2

          => sum = 2+2 = 4

      2. B_col = [4, 2]

           - zip(A_row, B_col) = zip([1, 2], [4,2])

                1 - 1. a = 1, b = 4 -> a*b = 4

                1 - 2. a = 2, b = 2 -> a*b = 4

         => sum = 2+4 = 6

--> [4, 8]

 

이렇게 각 A_row를 반복하면 결과 값이 나온다.

 

 


참고

 

zip

 zip()은 동일한 개수로 이루어진 반복 가능한(iterable) 자료형을 같은 인덱스끼리 묶어주는 역할을 하는 함수이다. 사용 예제 출력 a = [1, 2, 3, 4, 5] b = ['a', 'b', 'c', 'd', 'e'] for i, j in zip(a,b):..

hwayomingdlog.tistory.com

 

728x90
반응형