코딩 (독학)/★ Algorithm

[백준] 15552번 : 빠른 A+B - Kotlin [코틀린]

짱득이 2022. 4. 15. 20:20
300x250
반응형


  • 문제
 

15552번: 빠른 A+B

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

www.acmicpc.net

 

 


  • 알고리즘

BufferedReader 와 BufferedWriter를 사용하여 각 입력 값들의 덧셈을 하여 출력한다.


  • 풀이

먼저 여태까지의 모든 문제 풀이들은 비교적 사용이 간편한 Scanner와 단순한 println 을 사용했다.

그러나, 이런 풀이 방법은 내부적으로 많은 공정이 이루어지기 때문에 심각한 비효율적 검사가 발생하고, 당연히 처리 속도가 굉장히 느려진다.

 

그렇기 때문에 BufferedReader와 BufferedWriter를 사용하여 본 문제를 풀 수 있도록 의도한 것 같다.

 

일단 단순하게 생각한 원래대로의 풀이 먼저 써보자면..

 

 - 내가 쓴 풀이

import java.util.Scanner

fun main() : Unit = with(Scanner(System`in`)) {
    val T = nextInt()
    
    for(i in 1..T) {
        println("${nextInt() + nextInt()}")
    }
}

위와 같이 실행했을 때, 시간 초과가 나지 않는 InputStream 이었다면 당연히 가능한 코드였을테지만, 출제자의 의도대로 나는 함정에 빠졌고 시간 초과가 발생하였다.

 

 

 - 참고한 풀이

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

fun main() : Unit {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val bw = BufferedWriter(OutputStreamWriter(System.out))
    
    repeat(br.readLine().toInt()) {
        val token = StringTokenizer(br.readLine())
        val sum = (token.nextToken().toInt() + token.nextToken().toInt())
                    .toString()
                // token 입력 받은 후 +연산 하고, 전체를 String으로 변환
        
        bw.write(sum + "\n")
    }
    bw.flush()
    bw.close()
}

먼저 위 코드로 하면 시간 초과가 발생하지 않는다.

 

한 줄씩 설명 하자면

 

  • BufferedReader 객체를 생성하여 br 변수에 주소지를 할당 해 준다.
  • 마찬가지로 bw 변수에도 BufferedWriter 객체를 할당 해 준다.
  • 문제에서 제시한 TestCase의 개수 T를 받기 위해 br.readLine() 메서드를 통해 버퍼에서 입력을 받고, Int 형으로 변환하여 repeat 메서드로 TestCase를 반복할 수 있게 해준다.
  • br.readLine()을 통해 정수 2개를 입력 받고, StringTokenizer에 넘겨주면 공백을 기준으로 Token으로써 String을 split 해 준다. (여기서 사실 정수가 아니라 String으로 입력 받게 되는거라서 .toInt() 해 주어야 함.)
  • 2개의 토큰을 받아 각각 Int형으로 변환 후 + 연산을 해 준다.
  • 2개의 토큰에 대해 다시 String으로 변환하여 변수 sum 에 대입 해 준다. (이런 과정을 거치는 이유는 뒤에 사용 할 BufferedWriter(bw)의 write() 함수가 Int형 파라미터를 '숫자'가 아닌 '아스키 코드' 값 (10진수 인코딩 값)으로 처리하여 정상적인 값이 출력되지 않기 때문이다.
  • sum 문자열과 개행을 bw.write() 메서드를 통해 Output Buffer에 올려놓는다. (여기서 중요한 점은, 콘솔에 출력 되는것이 아니라 버퍼에 올라가만 있는 상태다.)
  • 이렇게 repeat을 돌며 Buffer에 올라간 문자열들을 나중에 한번에 bw.flush() 메서드를 통해 내뿜기 해 준다. (출력) repeat 메서드 안에 flush를 두지 않는 이유는 그때 그때 출력 해주게 되면 백준에서 타임아웃이 뜨기 때문이었다.
  • Buffer는 사용 후 반드시 꼭 close()를 해 주는 습관을 가져야 한다. (문제는 없지만, 안전성을 위해...)

  • 결과

맨 아래는 1차원적으로 풀었을 때 이고... 몇번의 시도 끝에 어색한 BufferedReader의 사용법을 숙지했다...ㅎ

 

 

참고한 링크

 

 

💡 [Kotlin] 빠른 입출력(I/O) - BufferedReader, BufferedWriter (예제 : BOJ 15552)

Java에는 Scanner.next()와 System.out.println()의 기본적인 입출력 함수들이 존재합니다. 마찬가지로, Kotlin에는 readLine()과 println()의 기본적인 입출력 함수들이 존재합니다. (물론, Kotlin에서 스캐너와..

meoru-tech.tistory.com

 

 

JAVA [자바] - 입력 뜯어보기 [Scanner, InputStream, BufferedReader]

이 글을 지금 이 시점에 써야 할까 고민을 많이 했다. 사실 자바를 그냥 다룰 줄만 아는 것에 목표를 둔다면 이 글이 무의미할 수도 있다. 그러나 자바에 대해 조금이라도 관심이 있고 더 배우고

st-lab.tistory.com

 

 

 

 

 

#Kotlin #Android #Develop #코틀린 #안드로이드 #개발 #AppDevelop #앱개발

#baekjoon #github #백준 #깃헙 #깃허브 #프로그래밍 #앱개발자 #개발자 #취준 #취준생

#알고리즘 #Algorithm #문제풀이

728x90
반응형