[Java] 스트림정의와 Scanner와 BufferedReader차이, BufferedReader사용한 백준 15552번 문제 풀이

    스트림 정의

    자바에서 데이터를 외부에서 읽고 다시 외부로 출력하는 작업을 할때 이 데이터는 스트림(Stream)을 통해 입출력된다. 스트림은 단일방향으로 연속적으로 흘러가는 것으로 수도꼭지를 생각하면 된다. 물은 계속 흘러나오는데 수도꼭지를 잠그면 물이 안나오고 풀면 물이 나온다.

     

     스트림은 InputStream(입력 스트림), OutputStream(출력 스트림)이 있는데 프로그램이 데이터를 입력받을때는 InputStream, 보낼때에는 OutputStream 이다. 스트림의 특성이 단방향이여서 입력과 출력을 모두 할 수 없어 스트림이 입력, 출력 따로 있는것이다.

     

    스트림 클래스는 크게 두 종류로 구분되는데 하나는 바이트(byte) 기반, 하나는 문자(character) 기반이다.

    바이트 기반은 그림, 멀티미디어, 문자 등 모든 종류의 데이터를 받고 보낼 수 있으나, 문자 기반 스트림은 오직 문자만 받고 보낼 수 있도록 특화 되어 있다.

    자바에서 콘솔입출력을 위해 입력 하기 위해선 Scanner(System.in) 을 사용했는데 여기서 System.in이 InputStream 타입의 필드이고,

    출력을 하기위해 사용한 System.out.println() 에서 System.out이 OutputStream 타입의 필드 이다. println()함수는 PrintStream 클래스의 함수인데 PrintStream으로 구현된 메서드로 자동적으로 flush()를 하여 버퍼에 있는 데이터를 모두 출력해준다.  

     

    Scanner와 BufferedReader 클래스 차이

    자바에서 데이터를 입력하기 위해 Scanner를 이용했다 하지만 속도면에서 더 빠른 BufferedReader가 있다. 백준 15552번 문제처럼 빠른 입출력을 요하는 알고리즘 문제를 풀기위해서는 BufferedReader를 사용해야 한다. BufferedReader가 더 빠를수 있는 이유는 Buffer Size가 더 크고 문자열을 파싱하지 않기 때문이다. Scanner는 문자열을 파싱하기 위해서 많은 정규식이 들어가있다. 그래서 한글자씩 읽을때마다 정규식을 거치기 때문에 상당히 비효율 적이지만 편의성이 좋아서 보통 Scanner를 사용하는 것이다.
    BufferedReader는 readLine() 함수를 이용해서 문자열만 읽을수있고, Scanner는 nextInt(), nextDoutble(), nextLine() 등으로 여러가지 형태로 입력받을 수 있다. 

     

    BufferedReader 클래스를 요하는 백준 15552번 문제

    https://www.acmicpc.net/problem/15552

     

    public class FastAplusB {
        static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    
        public static void main(String[] args) throws IOException {
            int t = Integer.parseInt(br.readLine());
            new FastAplusB().solve(t);
        }
        public void solve(int t) throws IOException {
            while(t>0) {
                StringTokenizer st = new StringTokenizer(br.readLine());
    
                int a = Integer.parseInt(st.nextToken());
                int b = Integer.parseInt(st.nextToken());
    
                bw.write(a + b + "\n");
                t--;
            }
            bw.close();
        }
    }

    BufferedReader 클래스는 readLine()으로 한 라인을 읽어 들이고 이것을 한 문자열로 받아온다. 그래서 이 문자열에서 데이터를 구분하기 위해서 StringTokenizer 클래스를 사용한다. 그래서  "1 2 3 4"로 들어오는걸 1, 2, 3, 4 한 문자씩 공백단위로 가져와서 데이터를 파싱하는것이다. 그리고 IOException을 던져줘야 한다. 이런 번거러움 때문에 Scanner를 사용하지만 속도때문에 BufferedReader를 사용하는 것이다.

     

     

    참고 : 이것이 자바다 http://www.yes24.com/Product/Goods/15651484

    참고 : https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/PrintStream.html

    그림 출처 : https://blog.naver.com/plateauh/222085091595

    참고 : https://carpediem0212.tistory.com/11

    댓글

    Designed by JB FACTORY