성장일기

 자바에서 데이터를 입출력 하는 방법으로 흔히 Scanner와 System.out.prinln()을 보통 떠올릴 것이다. 하지만 코딩테스트에서는 똑같은 알고리즘을 구현하더라도 입출력을 위해 Scanner, System.out.println()를 쓰는 것과 BufferedReader, Bufferewriter를 쓰냐에 따라서 시간초과 판정을 받을 수 있다.

 

 

 아래의 백준 "15552번: 빠른 A+B"문제에서 이를 확인할 수 있다. Scanner와 System.out.println()을 쓰면 시간 초과판정을 받게 될 것이다.

 

15552번: 빠른 A+B

첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.

www.acmicpc.net

 따라서 코딩테스트에서는 데이터 입출력을 위해 BufferedReader, BufferedWriter를 사용해야하는 이유를 알 수 있다.

 

 

 

1. BufferedReader


 BufferedReader는 사용자로부터 데이터를 입력받을 때 쓰이며, line단위 즉, Enter만으로 경계를 나누고 String으로 반환하기 때문에 코테에서 연산을 수행하기 위해서는 이를 정수형태로 변환을 해주어야 한다.

 

 

 메소드 readLine()은 개행기준으로 데이터를 한 줄로 읽어서 String으로 반환하는 메소드이다. [아래 코드 참고]

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

public class Solution {

	public static void main(String[] args) throws IOException{
		// BufferedReader를 사용하기 위해서는 throws IOException을 해주어햐 한다.
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(br.readLine());	// BufferedReader를 통해 정수 n입력 받기
	}

}

 

 

 

 코테에서는 데이터를 띄어쓰기 기준으로 1 2 3 4 5과 같은 형태로 데이터를 입력받아야 하는 경우가 있다. 따라서 개행단위로 입력을 받는 readLine()으로는 이를 구현할 수 없으므로 부가적으로 StringTokenizer나 split()을 통해 "1", "2" ..."5"로 따로 입력을 받고 배열에 집어 넣어야 한다. [아래 코드 참고]

1.1 StringTokenizer사용

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

public class Solution {

	public static void main(String[] args) throws IOException{
		// BufferedReader를 사용하기 위해서는 throws IOException을 해주어햐 한다.
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(br.readLine());	// BufferedReader를 통해 정수 n입력 받기
		int[] array = new int[n];
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		for(int i=0; i<n; i++) {	// n만큼 배열에 띄어쓰기로 입력받기
			array[i] = Integer.parseInt(st.nextToken());
		}
	}

}

 StringTokenizer를 이용하여 반복문을 이용하여 배열에 일일히 저장한다.

 

1.2 String.split() 사용

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

public class Solution {

	public static void main(String[] args) throws IOException{
		// BufferedReader를 사용하기 위해서는 throws IOException을 해주어햐 한다.
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int n = Integer.parseInt(br.readLine());
		String array = br.readLine();	// BufferedReader를 통해 "1 2 3 4 5"형식 입력 받기
		
		String[] arrays = array.split(" ");
		int[] arrayi = new int[n];
		
		for(int i=0; i<n; i++) {
			arrayi[i] = Integer.parseInt(arrays[i]);
		}
	}
}

 이 방법은 String형 배열에 담긴 문자열을 연산을 위해 int형으로 바꿔줘야하므로 번거로워서 잘 쓸 것 같지않다.

 

 

 

 

2. BufferedWriter


 BufferedReader는 데이터를 출력할 때 쓰이며, write()메소드를 통해 출력할 내용을 담고, flush()를 통해서 버퍼를 비워내는 동시에 콘솔에 출력한다. write()은 단지 버퍼에 담는 과정이며, 콘솔에 출력하기 위해서는 반드시 flush()를 호출해줘야한다. 그리고 출력이 끝났으면. close()를 통해서 스트림을 닫는다. [아래 코드 참고]

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.StringTokenizer;

public class Solution {

	public static void main(String[] args) throws IOException{
		// BufferedReader를 사용하기 위해서는 throws IOException을 해주어햐 한다.
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		
		int n = Integer.parseInt(br.readLine());	// BufferedReader를 통해 정수 n입력 받기
		int[] array = new int[n];
		
		StringTokenizer st = new StringTokenizer(br.readLine()); 
		for(int i=0; i<n; i++) {	// n만큼 배열에 띄어쓰기로 입력받기
			array[i] = Integer.parseInt(st.nextToken());
		}
		
		bw.write("ing형 String으로 변환 출력: \n");
		for(int i=0; i<n; i++) {
			bw.write(String.valueOf(array[i]));
			bw.write(" ");
		}
		
		bw.flush();
		bw.close();
	}
}

 BufferedWriter을 사용시 정수를 그대로 출력하려고 할 경우에 제대로 출력되지 않는다. 따라서 BufferedWriter에 넣을 때, String형으로 변환이 필요하다.

 

 

 

마무리


 파이썬으로 코딩테스트 연습을 하다가 백엔드 기업모집 공고도 여러 살펴봤는데, 기업모집공고 뿐만 아니라 코딩캠프나  기업 테크코스 같은 곳에서 백엔드 분야는 자바로만 코테를 허용한다는 것을 봤다. 물론 일부이지만 그래도 나중에 범용성 있게 지원? 하기 위해서 어차피 백엔드 분야로 자바 스프링으로 공부하고 있기에 그냥 자바로 넘어왔다. 

 

 하지만 파이썬으로 하다가 자바로 넘어오니깐 이런 입출력 같은 곳에서부터 코드량차이가 나기 시작한다. 어차피 코테는 알고리즘과 구현력 싸움이기에 익숙해지게끔 많이 연습해야겠다.

 

 

 

도움받은 곳(출처):

BufferedReader와 BufferedWriter의 사용법 (JAVA) (tistory.com)

[Java] BufferedWriter Int형 출력 / BufferedWriter 정수 출력 — 개발하는 사막여우 (tistory.com)

StringTokenizer에대한 자세한 설명:

[JAVA 자바] StringTokenizer 클래스로 문자열 분리하기! split 비교. (tistory.com)

 

공유하기

facebook twitter kakaoTalk kakaostory naver band