문제 제목 : 행렬 덧셈


문제

N * M 크기의 두 행렬 AB 가 주어졌을 때,

두 행렬을 더하는 프로그램을 작성하시오.

입력

첫째 줄에 행렬의 크기 NM 이 주어진다.

둘째 줄 부터 N 개의 줄에, 행렬 A 의 원소 M 개가 차례대로 주어진다.

이어서 N 개의 줄에 행렬 B 의 원소 M 개가 차례대로 주어진다.

NM 은 100 보다 작거나 같고,

행렬의 원소는 절대값이 100 보다 작거나 같은 정수이다.

출력

첫째 줄부터 N 개의 줄에 행렬 AB 를 더한 행렬을 출력한다.

행렬의 각 원소는 공백으로 구분한다.


예제 입력 1

3 3
1 1 1
2 2 2
0 1 0
3 3 3
4 4 4
5 5 100

예제 출력 1

4 4 4
6 6 6
5 6 100


우선, 예제의 입력과 출력을 보면 알 수 있듯이,

3 * 3 크기의 행렬의 덧셈은, 같은 자리의 수를 더한 결과의 같은 크기의 행렬이란 것을 알 수 있다.

만약 행렬의 곱셈이라면, 조금의 절차가 더해져 바로 실버 3-4 문제 급이 되었을 것이다.


이번 문제는, 서로 다른 배열이 있는데, 같은 행과 열의 수를 가지고 있다.

즉, 같은 모양이라는 것이다.

이번 문제는 초심자에게 있어, 배열을 접근하는 방법을 숙지하도록 안내 해 주고 있다.


나도 초심자의 마음으로 돌아가며, 이 문제에서 유도하고 있는 관심사항을 풀이 해 보자 :

  1. 2차원 배열의 생성 방법
  2. 2차원 배열의 동적 크기 할당 방법
  3. 2차원 배열의 원소 할당 방법
  4. 2차원 배열의 원소 추출 방법

1, 2번

자바에서의 2차원 배열의 생성 방식은 C 언어에서 파생 된 만큼,

거의 동일하지만, 선언 방식의 차이점이 존재한다.

만약 C 언어라면,

int numbers[5] 이러한 방식으로 선언 될 것이며,

동적 힙 메모리 할당의 경우, int * numbers = (int*)malloc(sizeof(int) * 5);

Java 에서는,

int[] number = new int[5]; 로 선언 된다.


즉, Java 에서는 복잡한 방식의 힙 메모리 동적 할당을 new int[5] 라는 문법으로 축약시킨 것이다.


자바에서 2차원 배열을 생성하는 것은 위의 문법과 더불어, 더욱 쉽다.

public class Main {
    public static void main(String[] args) {
        int a = 3, b = 5;

        int[][] arr = new int[a][b];
    }
}

위의 방식으로, 방금 행의 개수(row) 는 3,

열의 개수(column) 는 5 인 테이블이 만들어 진 것이다.


이 때, 정확하게 알아야 하는 것은, arr 변수는 하나의 주소로서 활동하게 된다는 것이다.

하지만, C 언어와 달리, &, * 와 같은 주소 접근자, 선언자는 작성 할 필요가 없다.

그저 배열의 인덱스로서 곧바로 접근이 가능 할 뿐이다.


3번, 4번

2차원 배열을 접근하기 위한 문법은 굉장히 간단하다.

순서는 [행][열] 로서, [0][0], [0][1], ... 이다.

하지만, 우리가 직관적으로 배열의 위치를 머리속에서 특정할 수 있는 방법은 무엇일까?


그 방법은, 행 (row) 라는 의미와, 열 (column) 이라는 의미를 확실히 이해하는 것이다.

열 column 열 column 열 column
행 row [ 0, 0 ] [ 0, 1 ] [ 0, 2 ]
행 row [ 1, 0 ] [ 1, 1 ] [ 1, 2 ]

위의 테이블은 int[][] arrs = new int[2][3];

이러한 문법이 선언되었을 때, 나타나는 테이블이다.

그리고 내부에 들어있는 원소는, 내가 나타낸, 해당 원소에 접근하기 위한 인덱스 를 보기 좋게 표현 한 것이다.


앞으로 배열을 다룰 때, 배열을 선언하고 추출하는 행동에서, 어떠한 원칙을 머리에 박아놓는 것은

앞으로 알고리즘을 다룰 때, 배열을 사용하는 다른 종류의 문제에서,

해당 문제가 제시하는 본질에 더 집중 할 수 있게 도울 것이다.


public class Main {
    public static void main(String[] args) {
        // 행 2, 열 3 의 2차원 배열 테이블 생성 - 명시적 선언 
        int[][] arrs1 = {
                {1, 2, 3},
                {4, 5, 6}
        };

        // 동적 생성 후, 원소 직접 주입.
        int[][] arr1 = new int[2][3];

        arr1[0][0] = 1;
        arr1[0][1] = 2;
        arr1[0][2] = 3;

        arr1[1][0] = 4;
        arr1[1][1] = 5;
        arr1[1][2] = 6;

        System.out.println(arr[1][2]);
        // 6
    }
}

이제 문제를 풀어보자

Answer

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        // 동적 크기의 배열을 힙 메모리에 저장한다. - N * M 크기 
        int[][] matrixA = new int[N][M];
        int[][] matrixB = new int[N][M];

        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                matrixA[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for(int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                matrixB[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        // 따로 배열을 생성 할 필요 없이, matrixA 에 합을 저장하자.
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M; j++) {
                matrixA[i][j] += matrixB[i][j];
            }
        }

        // 결과 출력
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M; j++) {
                sb.append(matrixA[i][j]).append(" ");
            }
            sb.append("\n");
        }

        System.out.println(sb.toString());
    }
}

'백준-단계별로 풀어보기 > 7-2차원 배열' 카테고리의 다른 글

백준 2563 Java - 색종이  (0) 2024.10.30