백준 자바 입출력 템플릿
류호석님의 자바 템플릿
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static FastReader scan = new FastReader();
//정답은 sb에 append 를 사용하여 출력
//만약 개행까지 출력하고 싶으면 append('\n')을 추가
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
input();
}
static void input(){
}
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
분석
- 자바에서 가장 성능이 좋은 입력 처리 방식 중 하나인
BufferedReader
를 사용했다.BufferedReader
는 대량의 데이터를 읽을 때, 특히 텍스트 데이터를 처리할 때 효과적이다.
- 기본적으로 문자 읽기로 사용되도록 설계되었으며, 파일을 읽는 경우를 위한 생성자도 준비되어 있다.
- 정의된 FastReader 클래스의 객체인 scan을 통해 쉽게 입력을 받을 수 있다.
- 출력을 위한 StringBuilder도 객체로 미리 생성되어 있다.
- FastReader는 기본적으로 다음 단어 하나를 읽는
next()
와 다음 문장 1줄을 읽는nextLine()
이 구현되어 있다. - 그 외에 각 타입에 맞게
next()
를 사용하여 파싱하는nextInt()
,nextLong()
,nextDouble()
이 있다.
BufferedReader
- 기존 입력 방식에서의 문제는 너무 느리다는 것이다.
- 구조적으로 문제가 있었는데, 바이트 단위로 데이터를 읽을 때마다 시스템을 호출했기 때문이다.
- 반면에
BufferedReader
는 한번에 한 줄의 데이터를 읽기 때문에 성능이 우세할 수 밖에 없었다. - 내부적으로 버퍼를 사용하여 데이터를 저장한다.
BufferedReader
는 문자 기반 스트림으로 바이트는 읽지 못한다.
InputStreamReader
BufferedReader
는 바이트는 읽지 못하기 때문에 입력 데이터(바이트 스트림)을 문자 데이터(문자 스트림)으로 바꿔줘야 한다.InputStreamReader
는 이 변환 과정을 담당한다.
StringBuilder
- 백준에서 결과를 출력하기 위해 문자열을 구성해야 하는 상황에서
StringBuilder
가 좋은 성능을 보인다. - String 객체는 때문에 어떤 문자열 객체에 수정을 가하면 사실은 새로운 String 객체가 생성되고 할당되는 것이다.
- 이전에 있었던 객체는 GC의 대상이 되고 이러한 과정은 많은 리소스를 소모할 수 밖에 없다.
- 그러나
StringBuilder
는 가변적이어서 새로 객체를 생성하지도 않고 GC에도 부담을 주지 않는다. 뿐만 아니라 문자열을 다루기 위한 다양한 기능을 지원한다.
사용 예시(BOJ 1021)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.io.*;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main {
static FastReader scan = new FastReader();
static StringBuilder sb = new StringBuilder();
// 실제 코드 작성은 여기서부터
static int n, m;
static LinkedList<Integer> deque = new LinkedList<>();
static int result=0;
public static void main(String[] args) {
input();
System.out.println(result);
}
static void input(){
n = Integer.parseInt(scan.next());
m = Integer.parseInt(scan.next());
for (int i=1;i<=n;i++){
deque.offerLast(i);
}
for (int i=0;i<m;i++){
solve(Integer.parseInt(scan.next()));
}
}
static void solve(int num){
int now = deque.indexOf(num);
int mid = deque.size()/2;
if (now == 0){
poll();
} else if (now<=mid) {
left(now);
}else{
right(deque.size()-now);
}
}
static void poll(){
deque.pollFirst();
}
static void left(int it){
for (int i=0;i<it;i++){
deque.offerLast(deque.pollFirst());
result++;
}
poll();
}
static void right(int it){
for (int i=0;i<it;i++){
deque.offerFirst(deque.pollLast());
result++;
}
poll();
}
// 여기까지다.
static class FastReader {
BufferedReader br;
StringTokenizer st;
public FastReader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
public FastReader(String s) throws FileNotFoundException {
br = new BufferedReader(new FileReader(new File(s)));
}
String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}
- input 함수에서 입력들을 받고 solve 함수를 만들어 문제풀이를 위한 로직을 작성한다.
- 필요에 따라 전역변수나 메서드를 추가 생성한다.
This post is licensed under CC BY 4.0 by the author.