[Troubleshooting] Go, Go 언어로 알고리즘 문제 풀 시 시간 초과하는 경우(버퍼로 입출력 구현하기)
(글쓴날 : 2020.02.26)
* Baekjoon Online Judge에서 2742번 문제를 풀다가 발생했습니다.
* 입출력 함수와 관련하여 시간 초과가 발생한 경우입니다.
문제 해결 과정
1) 원인 파악
당시 Baekjoon Online Judge의 2742번 문제(입력받은 수부터 1까지 내림차순으로 출력하는 문제)를 풀기 위해, 입출력 함수로 fmt 패키지의 Print() 시리즈 함수 및 Scan() 시리즈 함수와 같은 기본 입출력 함수를 사용함.
(ex)
1
2
3
4
5
6
7
8
9
|
// 사용했던 출력 함수
fmt.Print()
fmt.Println()
fmt.Printf()
// 사용했던 입력 함수
fmt.Scan()
fmt.Scanln()
fmt.Scanf()
|
* Baekjoon Online Judge 2742번 코드(실패, 시간 초과)
1
2
3
4
5
6
7
8
9
10
11
12
|
package main
import "fmt"
func main() {
var num int
fmt.Scan(&num)
for i := num; i >=1; i-- {
fmt.Println(i)
}
}
|
2) 해결 방법
입출력 관련 효율을 높이기 위해서 입출력 버퍼 관련 bufio 패키지와, 운영체제 기능 관련 os 패키지를 import 하여 io.Reader, io.Writer 인터페이스를 래핑 한 버퍼 스트림 입출력 함수를 구현해야 합니다.
(1) bufio 패키지의 NewReader(), NewWriter() 함수에 각각 os 패키지의 표준 입출력 스트림(Stdin, Stdout)을 인자로 넘겨 변수에 할당합니다.
(ex)
1
2
|
stdin := bufio.NewReader(os.Stdin)
stdout := bufio.NewWriter(os.Stdout)
|
(2) 할당된 NewReader 변수에서 ReadLine() 함수를 참조하여 문제에서 입력해주는 수를 스트림으로 입력받고 string화한 후 strconv 패키지의 Atoi() 함수로 string화 된 스트림을 다시 int로 형변환합니다.
(ReadLine() 함수는 반환값이 line []byte, isPrefix bool, err error의 3개이며, Atoi() 함수는 i int, err error의 2개이므로 필요 없는 반환값들을 _에 할당해 줍니다.)
(ex)
1
2
|
temp, _, _ := stdin.ReadLine()
num, _ := strconv.Atoi(string(temp))
|
(3) num에 할당된 문제에서 입력된 수를 기준으로 1씩 감소하는 반복문을 구현하여 출력하면 됩니다.
출력하실 땐 NewWriter 변수에서 WriteString() 함수를 참조하여, 반복 제어 변수 i를 strconv 패키지의 Itoa() 함수를 사용해 문자열로 변환하여 출력하시면 됩니다.
(마무리로 버퍼에 남아있는 스트림을 할당된 NewWriter 변수에서 Flush() 함수를 참조하여 제거해주셔야 합니다.)
(ex)
1
2
3
4
5
|
for i:= num; i >= 1; i-- {
stdout.WriteString(strconv.Itoa(i) + "\n")
}
stdout.Flush()
|
* Baekjoon Online Judge 2742번 코드(성공)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package main
import (
"bufio"
"os"
"strconv"
)
func main() {
stdin := bufio.NewReader(os.Stdin)
stdout := bufio.NewWriter(os.Stdout)
temp, _, _ := stdin.ReadLine()
num, _ := strconv.Atoi(string(temp))
for i:= num; i >= 1; i-- {
stdout.WriteString(strconv.Itoa(i) + "\n")
}
stdout.Flush()
}
|
이번 기회로 알고리즘 문제를 풀 때 입출력 부분에서 최대한 효율적으로 구현하는 것도 능력이라는 것을 깨달았습니다.
비단, Go 언어뿐만이 아니라 Python이나 Java와 같은 언어들도 입출력 관련 이슈가 존재하는 것 같은데 문제를 또 풀다가 직면하게 되면 다른 언어도 다뤄 보도록 하겠습니다.
지금 단순하게 드는 생각은 이렇게 간단한 문제를 푸는데 뭐가 이리 복잡한지, 그냥 scanf(), printf()만 써도 되는 C 언어가 역시 근본인가라는 생각이 듭니다... (하지만 쉬운 문제라 이렇게 느껴지는 게 함정.)
'Deprecated' 카테고리의 다른 글
[Baekjoon Online Judge] 백준 10718번 We love kriii(Python, Go) (0) | 2020.02.27 |
---|---|
[Baekjoon Online Judge] 백준 2557번 Hello World(Python, Go) (0) | 2020.02.27 |
[Go] Go 언어 예제와 기본 문법 정리 4탄(반복문 for, 함수 func) (0) | 2020.02.25 |
[React] React Hooks란 무엇인가? (2) | 2020.02.24 |
[Troubleshooting] React, create-react-app으로 프로젝트 시작 시 템플릿 생성이 안되는 문제 (0) | 2020.02.23 |