곽로그

[자바 이것저것 1] BufferedReader, BufferdWriter 사용하기 본문

language/java

[자바 이것저것 1] BufferedReader, BufferdWriter 사용하기

일도이동 2020. 1. 27. 18:06
반응형

 알고리즘을 풀다보면 입출력을 어떻게 하는 지에 따라 시간초과가 나는 경우가 종종 있다. 처음 알고리즘을 풀때는 Scanner 클래스를 많이 사용하지만, 테스트 케이스가 50만, 100만이 넘어가는 경우에는 Scanner를 사용하면 시간초과가 난다. 따라서 이 경우에는 BufferedReader, BufferedWriter를 사용해야 한다.

 

BufferedReader, BufferedWriter가 빠른이유

 

 입출력이 한 바이트나 문자단위로 이뤄지는 다른 클래스와는 달리 Buffered스트림은 내부적으로 8192바이트 크기의 배열을 가지고 있다.  따라서 이미 생성된 스트림에 배열 기능을 추가해 배열 단위로 빠르게 입출력을 할 수 있다. 

 IDE에서 BufferedReader 클래스를 열어보면 확인할 수 있다. 

 

BufferedReader 사용법

생성자

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

 

 BufferedReader에 어떤 생성자, 변수, 메서드가 있는지는 javadoc에서 확인할 수 있다. 

 

BufferedReader (Java SE 13 & JDK 13 )

 

docs.oracle.com

 우선 알고리즘을 위한 입력은 화면에서 받는 것이기 때문에 System.in으로 받아와야 한다. 이때 System.in은 InputStream으로 바이트 단위로 입력을 받기때문에 이를 문자단위로 받아올 수 있도록 보조스트림을 사용해야 한다. 보조스트림으로는 바이트스트림을 문자스트림으로 바꿔주는 InputStreamReader를 사용한다. 마지막으로 입력을 더 빠르게 받기위해 BufferedReader를 이용한다. 

 

new 예약어는 생략

 

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

 

메서드

 

 BufferedReader의 메서드 중 readLine을 사용해서 한 줄씩 입력을 받는다. 

https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/io/BufferedReader.html#%3Cinit%3E(java.io.Reader)

 

  이 때, redaLine의 경우 주의 해야할 점이 2가지 인데, 첫번째는 반환 값, 두번째는 입력이 line이라는 것이다. readLine은 반환 값이 String 이므로 사용해야할 값이 String이 아닐 경우 원하는 자료형으로 바꿔야 한다. 예를 들어 readLine으로 읽은 값 5를 int로 바꿔야 한다면 다음과 같이 String 에서 int로 변환을 해줘야한다. 

int T=Integer.parseInt(br.readLine());

  readLine의 입력단위는 한 줄이다. 따라서 한 줄에 2개의 입력값이 있는 경우에는 이를 따로 분리해주는 추가 작업이 필요하다. 많이 사용하는 방법은 StringTokenizer를 사용하거나 String의 split함수를 사용하는 방법 2가지이다. 

 

StringTokenizer

 

 예를 들어 입력으로 5 2 가 주어졌다고 하자. 이를 readLine으로 읽어들이면 5 공백 2으로 입력된다. 여기서 원하는 작업이 int a 에 5를 넣고 int b에 2를 넣는 것이라고 하자. 그러면 readLine으로 읽은 5 공백 2를 잘라야한다. StringTokenizer의 기본 구분자는 공백이므로 입력받은 각각의 문자가 하나의 토큰이 된다. 

String s=br.readLine();
StringTokenizer st = new StringTokenizer(s);
int a = Integer.parseInt(st.nextToken());
int b= Integer.parseInt(st.nextToken());

 

split

 String객체의 split함수에 대한 설명을 보면 

  regex를 매개변수로 받는 것을 볼 수 있는데, 위의 설명에 따르면 regex는 사용자가 원하는 구분자이다.  5 공백 2 에서 구분자는 공백이므로 " " 를 매개변수로 넘겨주면 된다. 

String[] split = s.split(" ");
int a= Integer.parseInt(split[0]);
int b= Integer.parseInt(split[1]);

여기서 line과 split을 한줄로 쓰면 좀더 깔끔해진다. 

String[] lineSplit = br.readLine().split(" ");

반응형

'language > java' 카테고리의 다른 글

[자바] Object 클래스 - hashCode() _작성중  (0) 2021.04.28
[자바] Object 클래스 - equals메서드  (0) 2021.04.22
Comments