[Java] 백준 2738번: 행렬 덧셈

hansung's·2024년 2월 21일
0

문제 url:
행렬 덧셈

문제:

🤔 문제 알아보기

  • 첫째 줄에 행렬의 크기 N과 M을 주어야 한다.
  • 총 행렬 A와 B를 더한 후 각 원소는 공백으로 구분하여 출력한다.
  • 그렇다면, 행렬A와 행렬B 결과값을 저장할 행렬result를 준비
  • N이 row를 담당하며 M은 col을 담당한다고 정의
  • 행렬A와 행렬B에 단어를 받은 후 StringTokenizer(공백으로 입력받으니) 클래스를 이용해 공백으로 구분 후 각 인덱스에 초기화

😎 준비하기

1. BufferedReader를 이용해 n과 m을 입력받는다.
2. 행렬A, 행렬B, 행렬result 배열을 n,m의 크기만큼 생성
3. 행렬A, B를 만들어야 하니 2번 반복하는 큰 반복문을 생성
4. row와 col에 해당하는 N과 M만큼 반복하여 인덱스에 StringTokenizer로 분리시킨 값으로 초기화
5. 그 후 result행렬에 A와 B를 넣은값을 초기화함과 동시에 출력

🐱‍👤 실제 코드

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

public class Main {
   public static void main(String[] args) throws IOException {
       BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       
       // 1. n과 m을 입력
       StringTokenizer st = new StringTokenizer(br.readLine());

       // 2. n과 m의 값 넣기, 배열 생성
       int n = Integer.parseInt(st.nextToken());
       int m = Integer.parseInt(st.nextToken());

       int a[][] = new int[n][m];
       int b[][] = new int[n][m];
       int result[][] = new int[n][m];


       // 3. 행렬 A와 행렬B 총 두개를 구하기 위한 반복문
       for (int k = 0; k< 2; k++) {

           if (k == 0) {
               // 4. 행렬 a에 입력하기 위한 반복문
               for (int i = 0; i< n; i++) {
                   st = new StringTokenizer(br.readLine());
                   for (int j = 0; j < m; j++) {
                       a[i][j] = Integer.parseInt(st.nextToken());
                   }
               }

           } else {
               // 4. 행렬 b에 입력하기 위한 반복문
               for (int i = 0; i< n; i++) {
                   st = new StringTokenizer(br.readLine());
                   for (int j = 0; j < m; j++) {
                       b[i][j] = Integer.parseInt(st.nextToken());
                   }
               }
           }

       }

       // 5. 행렬 덧셈과 출력을 하기 위한 for문
       for (int i = 0; i < n; i++) {
           for (int j = 0; j < m; j++) {
               result[i][j] = a[i][j] + b[i][j];
               System.out.print(result[i][j] + " ");
           }
           System.out.println();
       }

   }
}

드디어 2차원 배열까지 왔다 나름의 기쁨을 느낀 문제였지만, 풀면서 행렬간의 덧셈을 하는 방법, 값을 잘못 입력하여 발생한 오답 등의 트러블이 존재
이번에는 해당 코드를 리팩토링을 진행하면서 조금 더 시간을 줄이고 코드 간결화를 시켜보자

🐱‍👤 코드 리팩토링

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

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());

        // n과 m의 값 넣기
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        int result[][] = new int[n][m];

        // 행렬 첫번쨰꺼를 입력하기 위한 반복문
        for (int i = 0; i< n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < m; j++) {
                result[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        StringBuilder sbd = new StringBuilder();

        // 행렬 덧셈을 하기 위한 for문
        for (int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < m; j++) {
                sbd.append(result[i][j] + Integer.parseInt(st.nextToken())).append(" ");

            }
            sbd.append("\n");
        }
        System.out.println(sbd);

    }
}

타 블로그에 있던 코드를 발췌해서 연습해보았다.
이런식으로 하니깐 굳이 불필요한 for문을 줄일 수 있었고
StringBuilder로 바로 행렬B의 내용을 넣음과 동시에 출력할 수 있는 형태로 저장해
훨씬 빠르게 출력할 수 있었다.

372ms(기존코드) -> 184ms(리팩토링)
1667b(기존코드길이) -> 1163B(리팩토링 길이)
불필요한 for문과 배열생성 및 StringBuilder를 통한 성능 등으로
길이나 속도면에서도 줄일 수 있었다

🤢 회고

코드를 작성하는데, 로직을 조금 더 깊이 고민하는 연습이 필요해 보인다.
또한 이렇게 리팩토링을 하면서 더 나은 코드들을 연습하며 기존 코드의 단점들을 보완해보도록 해보자.

profile
ABAPER를 꿈꾸는 개발자

0개의 댓글