코딩테스트

백준 Java 입출력 방식

hyomee2 2024. 8. 4. 01:25

자바를 이용할 때

입력은 Scanner, 출력은 System.out.println()을

보통 이용해 왔다.

 

그런데 이 방식을 이용하면 백준에서 올바르게 푼 문제여도 시간 초과가 뜨는 경우가 있다고 한다.

Scanner는 BufferedReader보다 느리기 때문에

백준에서는 BufferedReader을 이용하는 방법이 권장된다.

또 System.out.println() 역시 속도가 느리기 때문에 BufferWriter가 권장된다.

 

Scanner가 BufferedReader보다 느린 이유를 간략하게 언급하자면

Scanner는 입력문자를 space, enter로만 구분하는데,

BufferedReader는 enter로만 구분하고 버퍼에 저장해두었다가

한 번에 내보내서 빠르다고 한다.

 

아래 링크에서 입력 속도를 확인할 수 있고,

https://www.acmicpc.net/blog/view/56

아래 링크에선 출력 속도를 확인할 수 있다.

https://www.acmicpc.net/blog/view/57

 

따라서 빠른 속도로 입출력 하는 방식을 정리해보고자 한다.

 

 

1. 입력받기

(1) 문자열을 입력받는 경우

// 기본적으로 import 해야하는 패키지들
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException { // throws IOException을 넣어줘야 한다.
        // 문자열을 입력받을 경우
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
    }
}

 

(2) 숫자를 입력받는 경우

// 기본적으로 import 해야하는 패키지들
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        // 숫자를 입력받을 경우 (BufferedReader.readLine()은 기본적으로 String으로 읽어오기 때문에 형 변환을 해주어야 한다.)
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(br.readLine()); // Integer.parseInt(String s)는 문자열을 정수로 변환하여 반환
    }
}

 

(3) 공백으로 한 단어씩 받는 경우

// 기본적으로 import 해야하는 패키지들
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
// 공백을 기준으로 한 줄을 나눠서 받고 싶을 때
import java.util.StringTokenizer;


public class Main {
    public static void main(String[] args) throws IOException {
        // 공백 구분해서 읽어올 경우 ex) 1 2 3 4 5
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       
        for (int i = 0; i < num; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine(), " ");  // 두번째 인자는 구분자
            int n = Integer.parseInt(st.nextToken());
            // nextToken()은 다음 입력을 가져오는 메소드
            /* hasNextTokens()는 다음 토큰이 있으면 true,없으면 false를 반환.
            while(st.hasNextTokens()) 처럼 사용 가능 */
        }
    }
}

 

 

2. 출력하기

(1) 문자열을 출력하는 경우

// 기본적으로 import 해야하는 패키지들
import java.io.*;
// 공백을 기준으로 한 줄을 나눠서 받고 싶을 때
import java.util.StringTokenizer;


public class Main {
    public static void main(String[] args) throws IOException {
        // 문자열을 입력받을 경우
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();

        // 문자열 출력
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write(str); // 출력 스트림으로 문자열 전부 보냄
        bw.flush();  // 버퍼에 남아있는 모든 문자열 출력(버퍼 비우기)
        bw.close();  // 혹시 버퍼에 데이터가 남아있을 수도 있으니 flush()을 통해서 스트림을 꼭 비워주자.
        
        // close()는 마지막에 한 번만 해주면 된다.

        // 줄바꿈은 "\n"으로 가능한데, bw.newLine()으로도 가능하다.
    }
}

 

(2) 숫자를 출력하는 경우

// 기본적으로 import 해야하는 패키지들
import java.io.*;
// 공백을 기준으로 한 줄을 나눠서 받고 싶을 때
import java.util.StringTokenizer;


public class Main {
    public static void main(String[] args) throws IOException {
        // 숫자를 입력받을 경우 (BufferedReader.readLine()은 기본적으로 String으로 읽어오기 때문에 형 변환을 해주어야 한다.)
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int num = Integer.parseInt(br.readLine()); // Integer.parseInt(String s)는 문자열을 정수로 변환하여 반환

        // 숫자 출력 (write는 String값으로만 출력이 가능해서 String.valueOf() 문으로 변환해주어야 한다.)
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        bw.write(String.valueOf(num));
        bw.flush();
        bw.close();  // 혹시 버퍼에 데이터가 남아있을 수도 있으니 flush()을 통해서 스트림을 꼭 비워주자.
        
        // close()는 마지막에 한 번만 해주면 된다.

        // 줄바꿈은 "\n"으로 가능한데, bw.newLine()으로도 가능하다.
    }
}