행복을 담는 블로그

[알고리즘] BufferedReader와 StringTokenizer 사용법 본문

Algorithm

[알고리즘] BufferedReader와 StringTokenizer 사용법

hyun0zin 2024. 9. 12. 12:43

가끔 백준 사이트 문제를 풀다보면 Scanner로 입력값을 받을 경우, 시간 초과가 나는 경우가 있어서 BufferedReader와 StringTokenizer 사용법에 대해서 간단하게 정리해보고자 한다.

(맨날 버퍼드리더 쓰는 법 까먹어서 내가 보려고 쓰는 글...)



Scanner v.s. BufferedReader의 차이

1. Scanner

가장 처음 입력을 받기 위해 알게된 Scanner 클래스이다.
java.util에 속해있는 클래스이다.

import java.util.Scanner;

public class Input {
    public static void main(String[] args) {

        // 1. java.util의 Scanner 클래스를 import 해와서 선언하기
        Scanner sc = new Scanner(System.in);

        // 2. 원하는 타입에 맞게 입력을 받으면 된다. 
        int N = sc.nextInt();
        String str = sc.next();
       }
}

Scanner의 특징

  1. 개행(줄 바꿈)과 공백(띄어쓰기) 기준으로 읽어온다.

따라서 한 줄에 여러 값을 입력 받을 경우, for문 등을 활용하거나 여러 변수에 담아서 받아주면 된다!

  1. 버퍼의 사이즈가 1024byte(1KB)이다.
  2. 데이터를 입력 받는 즉시 사용자에게 전송되어 시간이 많이 소요된다.



2. BufferedReader

데이터를 한 번에 쭉 읽어와서 버퍼에 보관을 한 후, 버퍼에서 데이터를 원하는 만큼씩 잘라서 읽어오는 방식이다.
사용자가 입력한 문자 스트림을 읽어온다.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public static void main(String[] args) throws IOException {

  // 1. BufferedReader를 사용하여 버퍼에 입력값을 모두 저장한다. 
  BufferReader br = new BufferedReader(InputStreamReader(System.in));

  // 2. 한 줄씩 원하는 값을 읽어온다.
  String st = br.readLine();

  // 3. 기본적으로 문자열로 값을 읽어오기 때문에, 원하는 타입으로 형변환을 해줘야한다.    
  int a = Integer.parseInt(br.readLine());
  int b = Integer.parseInt(st);
}

BufferedReader 특징

  1. 모든 입력값을 파싱하지 않고 한 번에 String으로 읽어온다. -> 버퍼에 저장
  2. 개행, 공백 등을 구분하지 않기 때문에 개행과 공백을 직접 처리해줘야한다.
    (br.readLine() 또는 StringTokenizer 등 사용)
  3. Checked Exception으로 반드시 예외처리를 명시해야한다!! (I/O Exception을 throw하거나 try/catch 처리 해야함)
  4. Thread safe 성질을 가지고 있어 멀티스레드 환경에서도 안전하다.

InputStringReader란?
: 바이트 단위로 읽어들이는 InputStream을 통해 입력 받은 뒤, 문자 단위로 데이터를 변환시키는 중개자 역할의 클래스

  • 입력 받은 문자값을 그대로 문자열로 출력한다.



https://www.acmicpc.net/blog/search/%EC%9E%85%EB%A0%A5+%EC%86%8D%EB%8F%84
BOJ 입력 속도 비교에서 알 수 있듯이, Scanner보다 BufferedReader로 값을 입력받는 시간이 훨씬 빠르다는 것을 알 수 있다.



StringTokenizer란?

돌고 돌아서 드디어 StringTokenizer...!! 그래서 그게 뭔데??

BufferedReader로 값을 입력을 받으면,,,

3
10 12 3 9
10 12 7 2
13 11 5 6

이렇게 개행과 공백문자가 포함된 상태로 들어오는 값도 모두 한 줄 단위로 String으로 들어오기 때문에, 공백 기준으로 문자 하나씩 가공해서 사용을 해야 한다.

그때 필요한 게 바로 StringTokenizer이다.



StringTokenizer 클래스란?

문자열을 구분자를 이용하여 분리할 때 사용할 수 있다.

BufferReader br = new BufferedReader(InputStreamReader(System.in));

String str = br.readLine();

// 1. 기본적으로 띄어쓰기 기분으로 문자열 분리
StringTokenizer st = new StringTokenizer(str);

// 2. 구분자를 넣어 구분자 기준으로 문자열 분리
StringTokenizer st = new StringTokenizer(문자열, 구분자);

StringTokenizer st = new StringTokenizer(str, ":");

이렇게 공백 또는 구분자를 기분으로 문자열을 구분하였다면, 해당 토큰을 하나씩 원하는 변수에 넣어주면 된다.

이때 분리된 문자열은 nextToken() 메서드로 확인할 수 있다.

BufferReader br = new BufferedReader(InputStreamReader(System.in));
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str);

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