AIL( Algorithm I Learned)

#AIL_23.12.13 // Programmers_행렬의 덧셈***

k0z 2023. 12. 13. 09:56

## AIL_행렬의 덧셈

*** 문제 설명
행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 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]]

 


## solution.JavaScript

1. 문제의 접근 방식

주어진 문제는 두 개의 행렬(arr1, arr2)을 입력으로 받고, 같은 위치에 있는 원소를 더한 결과를 반환합니다.

 

예시)

let arr1 = [[1, 2], [2, 3]];
let arr2 = [[3, 4], [5, 6]];
let result = solution(arr1, arr2);

console.log(result);

 

위의 예시에서 `arr1`과 `arr2`는 각각 다음과 같은 행렬을 나타냅니다. 

arr1 = [[1, 2],
        [2, 3]]

arr2 = [[3, 4],
        [5, 6]]
        
 arr1         arr2     arr1 + arr2
[1, 2]   +   [3, 4]   =  [4, 6]
[2, 3]   +   [5, 6]   =  [7, 9]
// 결과인 result는 [[4, 6], [7, 9]]이 됩니다.

2. 문제풀이

function solution(arr1, arr2) {
    // 결과를 저장할 빈 행렬 생성
    let answer = [];
    
    // 행렬의 행 수와 열 수 구하기
    let rows = arr1.length;
    let cols = arr1[0].length;
    
    // 각 위치의 원소를 더해서 새로운 행렬에 추가
    for (let i = 0; i < rows; i++) {
        let row = [];
        for (let j = 0; j < cols; j++) {
            row.push(arr1[i][j] + arr2[i][j]);
        }
        answer.push(row);
    }
    
    return answer;
}
/*
테스트 1
입력값 〉	[[1, 2], [2, 3]], [[3, 4], [5, 6]]
기댓값 〉	[[4, 6], [7, 9]]
실행 결과 〉	테스트를 통과하였습니다.
테스트 2
입력값 〉	[[1], [2]], [[3], [4]]
기댓값 〉	[[4], [6]]
실행 결과 〉	테스트를 통과하였습니다.
*/

 

1. `let answer = [];` 결과를 저장할 빈 배열 answer를 선언합니다. 이 배열에는 행렬 덧셈의 결과가 들어갑니다.

// 결과를 저장할 빈 행렬 생성
let answer = [];

 

2. `let rows = arr1.length;` 변수 `rows`에는 `arr1`의 행의 수를 저장합니다. `let cols = arr1[0].length;` 변수 `cols`에는 `arr1`의 열의 수를 저장합니다. 주어진 문제에서는 각 행의 열의 수가 같다고 가정하였으므로, arr1의 첫 번째 행의 열의 수를 사용합니다.

// 행렬의 행 수와 열 수 구하기
let rows = arr1.length;
let cols = arr1[0].length;

 

3. `for (let i = 0; i < rows; i++) {` 외부 루프는 각 행에 대한 작업을 반복합니다. i는 현재 행의 인덱스를 나타냅니다.

// 각 위치의 원소를 더해서 새로운 행렬에 추가
for (let i = 0; i < rows; i++) {

 

4. `let row = [];` 내부 루프에서 각 행에 대한 결과를 저장할 빈 배열 row를 선언합니다.

 // 내부 루프 시작 - 각 행에 대한 작업
    let row = [];

 

5. `for (let j = 0; j < cols; j++) {` 내부 루프는 현재 행의 각 열에 대한 작업을 반복합니다. j는 현재 열의 인덱스를 나타냅니다.

 for (let j = 0; j < cols; j++) {

 

6. `row.push(arr1[i][j] + arr2[i][j]);` 현재 위치에 있는 두 행렬의 원소를 더한 값을 `row` 배열에 추가합니다.

        // 현재 위치의 두 행렬 원소를 더해서 새로운 행렬에 추가
        row.push(arr1[i][j] + arr2[i][j]);
    }

 

7. `answer.push(row);` 내부 루프에서 한 행에 대한 계산이 완료되면, 해당 행을 최종 결과인 `answer` 배열에 추가합니다.

// 내부 루프 종료 - 한 행에 대한 작업이 완료됐으므로 해당 행을 answer에 추가
    answer.push(row);

 

8. `return answer;` 최종적으로 완성된 결과인 `answer` 배열을 반환합니다. 이 배열은 두 행렬을 더한 결과를 나타냅니다.

return answer;

3. 다른사람의 문제풀이 및 접근방식 분석_2중 map() 함수 사용***

function solution(A,B){
    return A.map((arr1, idx1) => arr1.map((val, idx2) => val+B[idx1][idx2]));
}
/*
테스트 1
입력값 〉	[[1, 2], [2, 3]], [[3, 4], [5, 6]]
기댓값 〉	[[4, 6], [7, 9]]
실행 결과 〉	테스트를 통과하였습니다.
테스트 2
입력값 〉	[[1], [2]], [[3], [4]]
기댓값 〉	[[4], [6]]
실행 결과 〉	테스트를 통과하였습니다.
*/

 

1.  `A.map`은 배열 A의 각 요소에 대해 주어진 함수를 실행하고 그 결과로 새로운 배열을 생성합니다. `arr1`A의 각 행에 해당하고, `idx1`은 현재 행의 인덱스를 나타냅니다.

A.map((arr1, idx1) => ...)

 

2. `arr1.map`은 현재 행 `arr1`의 각 요소에 대해 주어진 함수를 실행하고 그 결과로 새로운 배열을 생성합니다. ` val`은 현재 요소의 값이고, `idx2`는 현재 열의 인덱스를 나타냅니다.

arr1.map((val, idx2) => ...)

 

3. 현재 위치의 A 행렬과 B 행렬의 같은 위치에 있는 원소를 더합니다.

val + B[idx1][idx2]

 

4. 최종적으로, AB의 같은 위치의 원소를 더한 값으로 이루어진 새로운 행렬이 반환됩니다.


#  map() 함수란?

`map()`함수는 배열의 각 요소에 대해 주어진 함수를 호출하고, 그 결과로 새로운 배열을 생성합니다. 기존 배열을 변경하지 않고, 각 요소를 변형하여 새로운 배열을 만들 때 사용합니다.

 


#  map() 사용방법

** 기본구조

const newArray = array.map((element, index, array) => {
    // 변형 로직
    return transformedElement;
});

// element: 현재 요소의 값
// index: 현재 요소의 인덱스
// array: 원본 배열

** 예시

const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map((num) => {
    return num * 2;
});

// doubledNumbers: [2, 4, 6, 8, 10]

#  map() 장단점

** 장점

1. 간결성

 코드를 간결하게 작성할 수 있습니다.

 

2. 가독성

 변형 로직이 한 줄에 담겨 있어 가독성이 좋습니다.

 

2. 불변성 유지

 기존 배열을 변경하지 않고 새로운 배열을 생성하여 함수형 프로그래밍 원칙 중 하나인 불변성을 유지합니다.

 

** 단점

성능 고려 문제

`map` 함수를 사용하면 새로운 배열을 만들기 때문에, 큰 배열이나 성능이 중요한 상황에서는 오히려 부적절할 수 있습니다.


map() 사용시기

** 사용시기

1. 변형이 필요한 경우 

각 요소를 변형하고 새로운 배열을 만들어야 할 떼 사용합니다.

 

2. 불변성이 필요한 경우

기존 배열을 변경하지 않고 새로운 배열을 만들어야 할 때 사용합니다.

 

3. 가독성이 중요한 경우

`map`을 사용하면 변형 로직을 한 줄에 간결하게 표현 할 수 있습니다. 

** 사용 시 주의사항

1. 콜백 함수 주의

콜백 함수에서 부수 효과(side effects)를 피해야 합니다. map 함수는 변형 로직을 순수 함수로 작성하는 것이 좋습니다.

 

2.성능 고려

큰 배열이나 성능이 중요한 상황에서는 map 대신 다른 방법을 고려해야 합니다.

 

3.적절한 활용

단순한 반복문으로 처리 가능한 작업이라면 map을 사용할 필요가 없습니다. 코드의 목적과 상황에 맞게 선택해야 합니다.