JAVA / BufferedReader, BufferedWriter (백준 15552번)
백준 문제를 풀다가 늘 사용하던 Scanner 를 쓰면 안되는 문제를 만났다
https://www.acmicpc.net/problem/15552
시간제한이 있어서 Scanner 말고 다른방법을 사용해야하는 문제다
문제
첫번째로 테스트케이스의 개수를 입력받은 뒤 A+B 를 테스트케이스의 개수만큼 입력해준다
테스트 케이스에 입력한 수 만큼 A+B 를 입력했다면 입력한 테스트케이스들의 답이 출력되는 방식이다
Scanner 말고 다른 방법으로는 BufferReader 를 사용하는 방법이있다
BufferReader 는 Scanner 보다 빠르다
(입력된 데이터가 바로 전달되지 않고 버퍼를 거쳐 전달되므로 데이터 처리 효율성을 높인다)
하지만 BufferReader 는 Enter 만 경계로 인식하고 받은 데이터가 String으로 고정되기 때문에 입력받은 데이터를 가공하는 작업이 필요한 경우가 많다
이 문제 이후로 시간제한이 있는 다른문제들도 이방법을 사용해주면 좋다
문제를 풀기위해 BufferedReader 와 BufferedWrite 를 알아보자면
BufferedReader - Scanner 와 유사하다
BufferedWrite - System.out.println(); 와 유사하다
이 둘을 사용하려면 이것들을 import 해주어야한다
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
이클립스를 사용중이라면 ctrl + shift + o 를 눌러주면 자동으로 import 해준다
BufferedReader 사용법
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); //선언
String s = bf.readLine(); //String
int a = Integer.parseInt(bf.readLine()); //Int
입력은 readLine(); 메서드를 활용하는 여기서 주의해야할점이 있다
1. readLine();시 리턴값을 String으로 고정되기에 String이 아닌 다른 타입으로 입력을 받으려면 형 변환을 꼭 해주어야 한다
2. 예외처리를 꼭 해줘야한다 readLine을 할때마다 try & catch 를 활용하여 예외처리를 해줘도 되지만
보통 throws IOException 을 사용한다
throw 이용시에는
1. 클래스를 import 해줘야한다
import java.io.IOException;
2. main 클래스 옆에 throw IOException 를 작성한다
public static void main(String[] args) throws IOException {}
StringTokenizer st = new StringTokenizer(s); //StringTokenizer인자값에 입력 문자열 넣음
int a = Integer.parseInt(st.nextToken()); //첫번째 호출
int b = Integer.parseInt(st.nextToken()); //두번째 호출
String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음
Read 한 데이터는 Line 단위로만 나누어진다 이걸 공백단위로 데이터를 가공하려면 따로 작업을 해줘야하는데
위의 두가지 방법이 대표적이다
1. StringTokenizer 에 nextToken() 함수를 쓰면 readLine() 을 통해 입력받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다
2. String.split() 함수를 활용하여 배열에 공백 단위로 끊어서 데이터를 넣고 사용하는 방식이다
BufferedWrite 사용법
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); //할당된 버퍼에 값 넣어주기
String s = "abcdefg"; //출력할 문자열
bw.write(s+"\n"); //버퍼에 있는 값 전부 출력
bw.flush(); //남아있는 데이터를 모두 출력시킴
bw.close(); //스트림을 닫음
BufferedWrite 의 경우 버퍼를 잡아 놓았기 때문에 반드시 flush() / close() 를 반드시 호출해서 뒤 처리를 해줘야한다
그리고 bw.write 에는 System.out.println(); 과 같이 자동개행 기능이 없기 때문에 개행을 해줘야 할 경우에는 \n 를 통해 따로 처리해줘야한다
*flush() : 현재 버퍼에 저장되어 있는 내용을 클라이언트로 전송하고 버퍼를 비운다
*개행 : 다음줄로 바꾸는것 \n 같은 느낌