TIL 2022-01-10

그린·2022년 2월 2일
0

TIL

목록 보기
7/47

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을 이용하면 된다!

        (출처 : https://blog.naver.com/PostView.nhn?blogId=parkhj2416&logNo=221843949484&parentCategoryNo=&categoryNo=32&viewDate=&isShowPopularPosts=true&from=search)

        또는 String.split() 함수를 활용해서 배열에 공백 단위로 끊어서 데이터를 담을 수 있다.

        StringTokenizer st = new StringTokenizer(s); //StringTokenizer인자값에 입력 문자열 넣음
        int a = Integer.parseInt(st.nextToken()); //첫번째 호출
        int b = Integer.parseInt(st.nextToken()); //두번째 호출
        
        String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음

        (출처 : https://coding-factory.tistory.com/251)

    • 빠른 출력에 관해

      1) 초반 내 풀이

      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) 다음 내 풀이

      질의응답 게시판을 보니까 반복문 하나로도 가능하다고 하길래 다음과 같이 해봤으나 역시나 반복문 안에 비교가 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) {
              }
          }
      }

      3) 결국 찾아본 풀이

      결국 다른 분들의 풀이를 찾아보았는데 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();
      
          }
      }

      (코드 출처 : https://yongku.tistory.com/entry/%EC%BD%94%EB%93%9C%EC%97%85-%EA%B8%B0%EC%B4%88-100%EC%A0%9C-1084%EB%B2%88-%EB%B9%9B-%EC%84%9E%EC%96%B4-%EC%83%89-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EC%9E%90%EB%B0%94JAVA)

      +) 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번

    • 2차원 배열을 이용해서 풀 때 x좌표는 왼쪽 축 기준, y좌표는 위쪽 축 기준으로 생각하면 된다!(2차원배열 구조를 생각하기)

3. 느낀 점

마지막쪽으로 갈수록 내 기준 약간 어려워져서 은근 오래 고민하고 조금 시간이 걸리긴 했는데 그래도 다 풀어서 정말 뿌듯하다! 그리고 그동안 Scanner를 이용해서 입력받고 System.out.println();으로 출력하는 방식이 익숙해서 이 방법들을 자주 사용했었는데, 오늘부터 BufferedReader랑 BufferedWriter를 주로 사용해서 하니까 이 부분에 있어서 틀리는 경우는 안 생겨서 좋았다. 앞으로도 계속 꾸준히 문제들을 풀면서 실력을 향상시켜야겠다. 코드업 100제 끝!:)

profile
기록하자

0개의 댓글

Powered by GraphCDN, the GraphQL CDN