소소한 컴퓨터 이야기

행렬의 덧셈

by Cori

문제

행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.

 

제한사항

· 행렬 arr1, arr2의 행과 열 길이는 500을 넘지 않습니다. 

 

입출력 예 

arr1 arr2 return 
[[1,2],[2,3]] [[3,4], [5,6]] [[4,6],[7,9]]
[[1],[2]] [[3],[4]] [[4],[6]]

풀이

1. Me

def solution(arr1, arr2):
    answer = []
    for i in range(len(arr1)):
        for j in range(len(arr1[i])):
            answer.append([arr1[i][j] + arr2[i][j]])                   
    return answer

[[1], [2]], [[3], [4]]를 입력으로 받았을 경우 정답([[4], [6]])을 출력하지만, [[1, 2], [2, 3]], [[3, 4], [5, 6]]을 입력으로 받았을 때 정답([[4, 6], [7,9]])이 아닌 오답([[4],[6],[7],[9]])를 출력한다.. 배열 내 덧셈을 구현하기 쉽지 않아 풀지 못했다.

 

2. Others

def sumMatrix(A,B):
    answer = [[c + d for c, d in zip(a, b)] for a, b in zip(A,B)]
    return answer

zip 함수를 이용하여 행렬 덧셈을 구현하였다. zip 함수의 작동 원리에 대해 알아본 뒤 다시 봐야 이해가 좀 더 쉬울 듯. . 

import numpy as np

def sumMatrix(A,B):
    A=np.array(A)
    print(A)  # [[1 2] [2 3]], [[1] [2]] 
    B=np.array(B)
    answer=A+B
    return answer.tolist()

numpy 라이브러리를 이용하여 행렬 덧셈을 구현하였다. numpy의 array 함수를 이용하여 행렬을 배열로 바꾸고, 덧셈을 수행한 후 다시 리스트로 반환하였다. numpy 함수의 활용법에 대해서도 공부가 필요한 것으로 보인다.

def sumMatrix(A,B):
    for i in range(len(A)) :
        for j in range(len(A[0])):
            A[i][j] += B[i][j] 
    return A

이 코드가 내가 구현하려 했던 코드와 가장 비슷하지 않을까 싶다. A행렬에 변환이 생기기 떄문에, 새로운 행렬을 만들고 거기에 연산 결과를 저장하여 반환하는 것이 좋을 것 같다.

 

-> 아래에서 2차원 리스트 선언법 학습 후 다시 작성한 코드 

def solution(A,B):  
    answer = [[0] * len(A[0]) for _ in range(len(A))]
    for i in range(len(A)) :
        for j in range(len(A[0])):
            answer[i][j] += A[i][j]
            answer[i][j] += B[i][j] 
    return answer

자료 정리

1. zip 연산자

0) 정의

-> 동일한 개수의 iterable 데이터를 같은 위치에 있는 아이템별로 그룹핑하여 그 결과를 iterator로 반환해 주는 함수 

    반환된 값은 tuple의 형태를 가지고 있다. 

 

1) 사용법 

numbers = [1, 2, 3]
letters = ['A', 'B', 'C']

for pair in zip(numbers, letters):
	print(pair)    # (1,'A'), (2, 'B'), (3, 'C')

for pair1, pair2 in zip(numbers, letters):
	print(pair1)    # 1 2 3 

list_t = [pair for pair in zip(numbers, letters)]	# [(1, 'A'), (2, 'B'), (3, 'C)]

# zip() 함수를 이용하여 사전 만들기 
dict(zip(numbers, letters))   # {1: 'A', 2:'B', 3:'C'}

2) 응용 - 다음 문제를 풀어보자

input_data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], output_data = [12, 15, 18]. f(input_dat) = output_data. f = ? 

# zip(* )으로 이중 리스트를 풀어 우리가 원하는 element가 모여있는 튜플로 변환 가능 
[element for element in zip(*input_data)]   #  [(1, 4, 7), (2, 5, 8), (3, 6, 9)] 
[sum(element) for element in zip(*input_data)]   # sum을 하여 [12, 15, 18] 

# zip(* ) 사용하지 않을 경우 
[a + b + c for a, b, c in zip(input_data[0], input_data[1], input_data[2])]

# map, list, zip 활용 
list(map(sum, zip(*input_data))

* 데이터 shape에 따라 zip을 사용할 것인지, zip(*)을 사용할 것인지 판단을 잘 해야 함 (중첩 리스트일 경우 zip(* )을 활용하여 리스트를 하나 줄여주는 것이 좋음)

 

3) zip unpacking  -> * 연산자 이용 

# 인자 해체하기 
pairs = [('a',1),('b', 2),('c',3)]

num_a, num_n = zip(*pairs)   # num_a: ('a','b','c'), num_n: (1, 2, 3)

4) zip() 과 enumerate()

list_a = ['a1', 'a2', 'a3']
list_b = ['b1', 'b2', 'b3'] 

for i, (a, b) in enumerate(zip(list_a, list_b)):
	print(i, a, b)  # 0 a1 b1 \n 1 a2 b2 \n 2 a3 b3

 

2. 이차원 리스트 만들기 

-> 파이썬에서는 다음과 같은 방법으로 이차원 리스트를 선언할 수 있다. 

# COLUMN = 가로 길이, ROW = 세로 길이 
array = [[0 for col in range(COLUMN)] for row in range(ROW)]
array = [[0] * COLUMN for _ in range(ROW)] 

# 다음과 같이 작성할 경우, 얕은 복사가 일어나기 때문에 권장하지 x 
array = [[0] * COLUMN] * ROW

* array = [[0] * COLUMN] * ROW와 같이 선언할 경우, 한 행에 대입연산을 수행하더라도 다른 행들이 영향을 받기 때문에 바람직하지 않은 선언방법이다.

'CS > Coding Test' 카테고리의 다른 글

모의고사  (0) 2021.08.23
정수 제곱근 판별  (0) 2021.08.23
K번째 수  (0) 2021.08.23
체육복  (0) 2021.08.22
예산  (0) 2021.08.22

블로그의 정보

코딩하는 오리

Cori

활동하기