1. 오늘 학습한 내용
코드업 기초 100제 1084 ~ 1099번
사용 언어 : 자바
2. 오늘 알게 된 내용
1084번
BufferedReader를 이용해 입력 받아야 할 때
한 줄 단위
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine(); //문자열
int num = Integer.parseInt(br.readLine()); //정수
공백 단위
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
int z = Integer.parseInt(st.nextToken());
StringTokenizer를 이용해 nextToken을 이용하면 된다!
또는 String.split() 함수를 활용해서 배열에 공백 단위로 끊어서 데이터를 담을 수 있다.
StringTokenizer st = new StringTokenizer(s); //StringTokenizer인자값에 입력 문자열 넣음
int a = Integer.parseInt(st.nextToken()); //첫번째 호출
int b = Integer.parseInt(st.nextToken()); //두번째 호출
String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음
빠른 출력에 관해
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
StringTokenizer st = new StringTokenizer(br.readLine());
int r, g, b;
r = Integer.parseInt(st.nextToken());
g = Integer.parseInt(st.nextToken());
b = Integer.parseInt(st.nextToken());
int count = 0;
for (int i = 0; i < r; i++){
for (int j = 0; j < g; j++) {
for (int k = 0; k < b; k++) {
System.out.printf("%d %d %d\n", i, j, k);
count++;
}
}
}
System.out.println(count);
} catch (IOException e) {
}
}
}
Scanner 객체로 입력을 받았던 것에서 BufferedReader와 StringTokenizer를 이용해 입력을 받아서 조금 더 빠르게 진행하였는데 시간초과라고 떠서 틀렸다고 나왔다. 해결 방법으로 중첩반복문 등등을 시간복잡도를 줄이는 방향으로 가보라는 방안이 나왔다.
질의응답 게시판을 보니까 반복문 하나로도 가능하다고 하길래 다음과 같이 해봤으나 역시나 반복문 안에 비교가 2번이나 있어서 사실 상 비슷한 시간복잡도를 가져서 시간초과라고 떴다. (출력은 똑같이 되었음.)
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
StringTokenizer st = new StringTokenizer(br.readLine());
int r, g, b;
r = Integer.parseInt(st.nextToken());
g = Integer.parseInt(st.nextToken());
b = Integer.parseInt(st.nextToken());
int count = 0;
int n1 = 0, n2 = 0, n3 = 0;
for (int i = 0; i < r*g*b; i++){
System.out.printf("%d %d %d\n", n1, n2, n3);
n3++;
if (n3 >= b) {
n2++;
n3 = 0;
}
if (n2 >= g) {
n1++;
n2 = 0;
}
count++;
}
System.out.println(count);
} catch (IOException e) {
}
}
}
결국 다른 분들의 풀이를 찾아보았는데 BufferedWriter를 이용해 아예 출력에서도 시간을 확 줄여버리는 것을 알 수 있었다.
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String[] a = br.readLine().split(" ");
int count = 0;
for (int i = 0; i < Integer.valueOf(a[0]); i++){
for (int j = 0; j < Integer.valueOf(a[1]); j++) {
for (int k = 0; k < Integer.valueOf(a[2]); k++) {
bw.write(i + " " + j + " " + k + "\n"); //출력 효율 높임
count++;
}
}
}
bw.write(String.valueOf(count)); //출력 효율 높임
bw.flush();
}
}
+) BufferedWriter
많은 양의 출력에서는 Buffer를 활용하는 것이 좋다.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));//선언
String s = "abcdefg";//출력할 문자열
bw.write(s);//출력
bw.newLine(); //줄바꿈
bw.flush();//남아있는 데이터를 모두 출력시킴
bw.close();//스트림을 닫음
BufferedWriter 의 경우 버퍼를 잡아 놓았기 때문에 반드시 flush() / close() 를 반드시 호출해 주어 뒤처리를 해주어야 한다. 그리고 bw.write에는 System.out.println();과 같이 자동개행기능이 없기때문에 개행을 해주어야할 경우에는 \n를 통해 따로 처리해주어야 한다.
(설명 출처 : https://coding-factory.tistory.com/251)
1087번
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int num = Integer.parseInt(br.readLine());
int sum = 0;
for (int i = 0; sum < num; i++) {
sum += i;
}
bw.write(String.valueOf(sum));
bw.flush();
}
}
처음에 작성할 때 bw.write(sum);으로 했는데 출력이 정수가 아니라 아스키코드로 출력되는 것 같았다. 검색해보니까 String.valueOf(sum)으로 해서 출력하면 된다고 했더니 해결되었다.
(해결방법 출처 : https://www.acmicpc.net/board/view/22859)
1098, 1099번
3. 느낀 점
마지막쪽으로 갈수록 내 기준 약간 어려워져서 은근 오래 고민하고 조금 시간이 걸리긴 했는데 그래도 다 풀어서 정말 뿌듯하다! 그리고 그동안 Scanner를 이용해서 입력받고 System.out.println();으로 출력하는 방식이 익숙해서 이 방법들을 자주 사용했었는데, 오늘부터 BufferedReader랑 BufferedWriter를 주로 사용해서 하니까 이 부분에 있어서 틀리는 경우는 안 생겨서 좋았다. 앞으로도 계속 꾸준히 문제들을 풀면서 실력을 향상시켜야겠다. 코드업 100제 끝!:)