코드 저장소

공부에는 끝이 없다!

JAVA/코딩 테스트

백준 문제 풀이 - 입출력과 사칙연산 단계

VarcharC2K 2023. 8. 7. 14:30

코딩 테스트를 준비하며 백준의 기본 문제를 단계별로 풀어보기로 하였다.

원래는 프로그래머스에서 코딩 테스트를 준비하고 있었는데, 프로그래머스에는 입출력 단계가 빠져있어 실제 코테와 환경이 조금 달랐다.

평소 IDE 환경에 익숙해 있었던 터라 아예 깡코딩으로 하는 백준이 더 도움이 될것 같아 백준으로 다시 문제를 풀어기로 하였다.

 

첫날에는 가볍게 입출력과 사칙연산 모든 문제를 풀어보는 것으로 시작하였다.

크게 어려운 것은 없었고 좀 생각해 봐야할 것은 BufferedReader 쪽이였는데, 기존에 항상 Scanner만 사용하던 방식과 달라 새로웠다.

 

ChatGPT에게 BufferedReader에 대하여 물어보니 다음과 같은 답변을 받았다.

 

BufferedReader 클래스는 Java의 입출력 스트림을 이용하여 데이터를 효율적으로 읽어오는 데 사용되는 클래스입니다. BufferedReader는 입력 소스로부터 문자를 읽어오는데 사용되며, 내부적으로 데이터를 버퍼에 저장하고 한 번에 더 많은 데이터를 읽어오는 방식으로 성능을 향상시킵니다.

 

BufferedReader 클래스의 주요 특징과 사용법:

  1. 버퍼링: BufferedReader는 내부적으로 버퍼를 사용하여 데이터를 임시로 저장합니다. 이로 인해 실제 입출력 연산 횟수가 줄어들어 성능 향상을 가져옵니다.
  2. 문자 읽기: BufferedReader는 텍스트 파일이나 문자열과 같은 문자 기반의 데이터 소스로부터 문자를 읽어옵니다.
  3. 생성자: BufferedReader는 다양한 생성자를 제공하여 다양한 입력 소스와 연결할 수 있습니다. 예를 들어 InputStreamReader와 같은 다른 리더 클래스와 함께 사용하여 바이트 스트림을 문자 스트림으로 변환할 수 있습니다.
  4. 메서드: 주요 메서드로는 read(), readLine(), skip(), close() 등이 있습니다. read() 메서드는 한 문자씩 읽고, readLine() 메서드는 한 줄씩 읽습니다.
  5. 예외 처리: 입출력 작업은 예외가 발생할 수 있으므로 반드시 예외 처리를 해주어야 합니다.
  6. 사용 예시
try {
    // 입력 스트림을 생성하여 BufferedReader에 연결
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    
    // 데이터 읽기
    String line = br.readLine();
    int num = Integer.parseInt(line);
    
    // 버퍼 닫기
    br.close();
} catch (IOException e) {
    e.printStackTrace();
}

위 코드에서 BufferedReader는 System.in 스트림과 연결하여 표준 입력에서 데이터를 읽어옵니다. readLine() 메서드로 한 줄씩 읽고, Integer.parseInt() 메서드로 문자열을 정수로 변환합니다. 마지막에는 close() 메서드로 버퍼를 닫아 리소스를 해제합니다.

 

결론적으로, Scanner 와 같이 외부 입력을 받아오는 형태이나 속도 비교를 해보았을떄 Scanner보다 2배가량 빠른 것을 확인 할 수 있었다.

다만, Scanner의 경우 nextInt()와 같이 바로 int 형태로 외부 입력을 받아들이는 반면, BufferedReader는 String의 형태로만 입력을 받기 때문에 Integer.parseInt()등을 이용하여 형변환을 해줘야 편리하게 사용이 가능하였다.

 

다만, 입력하는 데이터가 특정 문자로 구분되는 경우, 한번에 데이터를 String[] 형태로 만들어 처리가 가능하다.

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] num = br.readLine().split(" ");

위의 코드 처럼, 문자열을 split 하여 배열에 담아두고 원하는 형태로 형변환 후 사용할 수 있다.

 

형변환 이야기가 나온 김에 약간 애를 먹었던 문제가 하나 있었는데,

2588번 : 곱셈의 문제를 3자리가 자연수가 아닌 여러자리의 자연수가 들어온다고 가정하고 for문을 이용하여 동적으로 계산이 되게 만들고 싶었는데...

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

class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] num = br.readLine().split(" ");
        int a = Integer.parseInt(num[0]);
        int b = Integer.parseInt(num[1]);
        for(int i = 0; i<num[1].length();i++){
            System.out.println(a * (int) num[1].charAt(i));
        }
        System.out.println(a*b);
        
    }
}

다음과 같이 코드를 구성하였으나 런타임 에러가 발생하였다.

가만히 생각해보니 Charater를 int로 형변환 하려면 다른 방법을 사용해야 하는데 직접 형변환 한것이 첫번째 문제, 뒤쪽 숫자부터 곱셈을 해야하는 데 for문에서 앞쪽부터 곱셈이 표시되게 한것이 2번째 문제였다.

 

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

class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int a = Integer.parseInt(br.readLine());
        String c = br.readLine();
        int b = Integer.parseInt(c);
        for(int i = c.length()-1; i>=0;i--){
            System.out.println(a * Character.getNumericValue(c.charAt(i)));
        }
        System.out.println(a*b);
        br.close();
        
    }
}

결과적으로 다음과 같이 for문을 바꾸고, Character의 getNumericValue 함수를 사용하여 각 String의 index에서 숫자를 하나하나 떼와 형변환 후 계산할 수 있었다.

Character를 형변환 하는 경우가 잘 없어서 잊고 있었는데 확실히 기초를 다시 다져봐야 할 것 같다.