[Java] 백준 입력값 받는 법(BufferedReader, next())

2023. 6. 13. 02:09프로그래밍/코딩테스트

1. 백준 코딩테스트 입력값 받는 법

백준 코딩테스트를 준비하려고 하는데 기존에 프로그래머스에서 진행하던 방식과는 입출력 방식이 조금 다른 형태라 당황했다.

우선 간단하게 정리하자면 백준에 답안을 제출할때는 다음과 같은 형식을 지켜야한다.

 

1. 클래스의 이름은 Main클래스, 이외에 package 경로는 없어야한다. 

2. 입력값이 주어진다고 하는 문제가 대부분인데 이 때 Scanner 혹은 BufferedReader를 통해 입력값을 받아야 한다.

뿐만 아니라 입력값이 첫 째줄에 띄어쓰기로 들어오느냐 개행 후 별개로 들어오느냐에 따라 처리방식이 달라진다.

 

현재까지는 다음과 같은 규칙들만 확인한 상태이다. 1번 규칙같은 경우는 쉽게 적용시킬 수 있으나 2번의 경우 초급자에게는 조금 난해할 수 있다. 백준에서는 다음과 같이 설명한다.

백준의 NumberFormat 에러에 관한 설명 글 중에서..

즉 위에서 설명한대로 첫번째 줄에 띄어쓰기로 입력값을 구분해서 전달하느냐 혹은 개행(\n)으로 구분하느냐의 차이다. 이 때 입력값은 Scanner의 next(),nextInt(),nextLine()등을 이용하거나 BufferedReader를 통해서도 받을 수 있다.

 

우선 next() 메서드의 경우 띄어쓰기로 입력값을 구분지을 수 있다. 그러나 구분 지은 요소를 반환하기 위해서는 다시 한 번 next()를 써주어야 한다.

Scanner sc = new Scanner(System.in);
String str1 = sc.next();
String str2 = sc.next();
System.out.println("str1 : " + str1 + "  str2 : "+ str2);

next() 메서드로 띄어쓰기로 입력받은 후 실행결과

str1에서 next()메서드를 통해 띄어쓰기로 한 번의 입력을 받게 되면 3과 5 두 개의 숫자가 스캐너를 통해 저장되게 된다. 그러나 str1은 현재 3이라는 값만 가지고 있다. 값을 받아오기 위해서는 한 번 더 next()를 통해 값을 반환해야 한다. 즉 백준에서 첫번째 줄의 띄어쓰기로 2개 이상의 입력값이 주어질 경우 위와 같이 작성해서 받아올 수 있다.

 

Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
System.out.println("str1 : " + str1 + "  str2 : "+ str2);

혹은 위와같이 연속해서 sc.nextLine()을 받아도 한 줄에서 입력받은 것으로 인식한다.

 

2. 입력받는 과정에서의 BufferedReader와 Scanner의 차이

백준에서는 메모리효율을 위해 BufferedReader 혹은 BufferedWriter를 사용하기도 한다.

기존의 Scanner와의 차이점은 우선 버퍼의 크기 차이이다. Scanner의 경우 1KB, BufferedReader의 경우에는 8KB의 공간을 가지고 있다고 한다. 그리고 Scanner는 사용자에게 입력을 받으면 받는대로 바로 데이터를 넘기기 때문에 비효율적이지만 BufferedReader는 일정 조건(버퍼의 공간이 가득찬다던지, 개행문자를 입력받는다던지)이 됐을 때만 데이터를 넘기기 때문에 훨씬 효율적이라 할 수 있다.

따라서 백준 코딩테스트에서는 제한된 메모리만을 사용하기 때문에 후반부에 고난이도의 문제를 풀 때 시간 초과 때문에 오답처리 되는 경우가 빈번하기 때문에 백준으로 코딩테스를 연습하는 사람에게는 입력값을 어떻게 처리하는가에 대한 고민은 필수적으로 알아야 할 기본 지식이라 생각된다. 

입력에서 BufferedReader를 이용하면 시간을 단축할 수 있듯이 답안을 제출할 때 역시 System.out.println();을 이용하지 않고 BufferedWriter를 이용하면 실행시간이 조금 더 단축된 결과를 볼 수 있다.

 

 

 

1. BufferedReader를 사용했을 때의 실행시간 결과

 

import 클래스 목록

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Scanner;
class Main{

    public static void main(String [] args){


        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        try{
            String [] str = br.readLine().split(" ");
            int result = Integer.parseInt(str[0])- Integer.parseInt(str[1]);
            bw.write(String.valueOf(result));
            bw.flush();

        }catch(Exception e){
            e.printStackTrace();
        }


    }
}

 

 

2. Scanner를 사용했을 때의 실행시간 결과

class Main{

    public static void main(String [] args){


        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        try{
            String [] str = br.readLine().split(" ");
            int result = Integer.parseInt(str[0])- Integer.parseInt(str[1]);
            bw.write(String.valueOf(result));
            bw.flush();

        }catch(Exception e){
            e.printStackTrace();
        }


    }
}