일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- toUpperCase
- 백준 2467번 용액 자바 - 이분탐색
- 백준 1197번 최소 스패닝 트리 - java
- 백준 1647번 도시 분할 계획 - java
- kotlin
- ac 5430번
- append
- HashMap
- 백준 3190번
- map
- HashSet
- 프로그래머스
- 백준 1541
- StringTokenizer
- dp
- StringBuilder
- mysql hy000 에러
- 최소 힙 1927
- 백준 1043번 거짓말 - java 분리 집합
- 코틀린기초
- hash
- Java
- 프로그래머스 java
- replace()
- 백준 2473번 세 용액 - java
- 18111번 마인크래프트 - java 구현
- 백준 14938번 서강그라운드
- 백준 1806번 부분합 java
- 프로그래머스 자바
- Stack
- Today
- Total
말하는 컴공감자의 텃밭
Java - BufferedReader, StringTokenizer, BufferedWriter 본문
BufferedReader, StringTokenizer, BufferedWriter
코테 준비하면서 자바 기본 I/O인 Scanner 만 사용했었다.
스캐너는 데이터 유형을 유연하게 선택할 수 있지만 속도가 느리다는 단점이 존재했다.
메모리와 속도적으로 알고리즘 문제 풀이에서 제한이 생기는 경우가 존재해서 방식을 바꾸려고한다.
백준 입력 속도 비교 https://www.acmicpc.net/blog/view/56
첫째 줄에 정수의 개수 N (= 10,000,000), 둘째 줄부터 N개의 줄에 한 개의 자연수(10,000 이하)가 적힌 파일을 입력받는데 걸리는 시간을 측정. 10번 측정해서 평균값으로 순위를 매김
버퍼 크기 | 실행 속도(백준 참고) | |
BufferedReader | 8KB | 0.6585 sec |
Scanner | 1KB | 4.8448 sec |
입출력 할 데이터가 많은 경우 위 차이는 더 두드러진다.
이러한 큰 차이는 아래 이유이다.
Scanner는 데이터 유형에 유연한 편이다.
입력받는 데이터를 token 단위로 잘라 반환하고. 이를 파싱(parse)한다고 할 수 있다.
데이터를 사용자가 필요에 따라서 원하는 타입으로 읽을 수 있다.
또한 스캐너는 하나하나 token으로 처리하므로 처리가 오래걸린다.
설거지를 하나 닦고 물로 행구는것보단 모두 닦아두고 한번에 행구는게 빠르듯 버퍼를 활용하는게 효율적이다.
BufferedReader은 단순히 String으로만 데이터를 읽어들인다.
readLine()을 활용하고 형변환을 위한 추가적인 코드가 필수적이다. 파싱을 하지 않으며
예외처리가 필수적이다. 버퍼를 활용하기에 월등히 빠른 속도를 자랑한다.
물론 입출력이 적은경우 버퍼의 크기가 작은 Scanner가 유리할 수 있다.
사용법
문제 하나를 입출력 받는 코드를 작성하며 사용법을 익혀보았다.
스캐너처럼 io와 util 라이브러리를 import 해주어야한다. 또한 예외처리를 해주어야한다.
BufferedReader와 BufferedWriter를 사용하여 입출력을 받아준다. 이 둘은 문자 입출력 버퍼 스트림이다.
줄단위로 읽어오기 때문에 StringTokenizer 또는 split()을 통해서 띄어쓰기를 구분해주어야 한다.
메서드
readLine() : 데이터를 String 형태로 한줄 읽어 옴.
newLine() : 줄바꿈 메서드
write : 입력 메서드
flush() : 버퍼에 남아 있는 데이터 출력. 버퍼를 비워준다.
close() : 스트림 종료
예제 적용 백준 2636번 중
입력 형태에 맞춰 사용해 보았다.
import java.util.*;
import java.io.*;
public class Main {// 2636번 치즈 G4
static int N,M,answer,cheese;
static int [][] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
arr = new int[N][M];
for(int i = 0; i<N; i++) {
st = new StringTokenizer(br.readLine());
for(int j = 0; j<M; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
bw.write(answer+"\n");
bw.write(cheese+"\n");
bw.flush();
bw.close();
}
}
한줄로 String 으로 받아 N과 M을 StringTokenizer st를 통해 정수형으로 형변환 해준다.
이후 치즈가 있는 부분 역시 st를 활용하여 하나하나 구분해서 배열에 넣어주었다.
앞으로 알고리즘을 풀면서 적응을 해봐야겠다.
위에 문제 포스팅
https://hb-in99.tistory.com/92
++ 추가내용
이제 알았는데 write는 정수형을 출력을 못했다.
버퍼에 숫자 6,2 따로 들어가서 62가 출력될줄 알았는데
아스키코드로 출력되는것 같았다.
이전 문제 '치즈'에서는
bw.write(time+"\n");
bw.write(last_cheese+"\n");
이런식으로 줄바꿈 문자가 더해져서 문자열로 형변환되어 문제가 없었던 것이었다.
찾아보니BufferedWriter 는 정수형이 char로 변환 되는것을 확인할 수 있었다.
만약 62가 입력으로 들어온다면. (char)62 로 '>' 가 'nextChar' 에 기록되고 ++ 되어 다음 문자를 받을 준비를 한다.
버퍼 writer로는 그럼 정수형을 출력할 수 없을까.
결론은 String으로 변환하여 출력하는 방법밖에 없었다. Scanner가 데이터 유형에 강하다는게 체감이 되넹
String.valueOf() 또는 + " " 을 활용해서 형변환 후 출력해주었다.
짜잘한건데 빠른 시간내에 알게되서 좋았다.
'백엔드 > Java' 카테고리의 다른 글
최소 신장 트리를 위한 프림, 크루스칼 알고리즘 (1) | 2024.08.28 |
---|---|
알고리즘 시간관련 - 시간 제한, 시간 복잡도 (0) | 2024.08.08 |
Java - Optional<> (0) | 2024.07.04 |
Java clone - 얕은복사 깊은복사 (0) | 2024.02.20 |