2023. 1. 30. 21:00ㆍIT/Algorithm
1. 문제 이해하기
영어 대소문자와 공백으로 이루어진 문자열이 주어진다.
문자열에 존재하는 단어의 개수를 출력하라.
(문자열의 길이는 1,000,000 이하)
2. 아이디어 구상
아주 간단한 문제다.
주어지는 한 줄의 문자열을 받아 공백을 기준으로 split을 한 후에 개수를 count하면 된다.
Python으로 풀 경우 코드 한 줄이면 끝난다.
<파이썬 풀이>
print(len(list(input().rstrip().split())))
그러나 Golang으로 풀 경우, 조금은 더 생각을 할 필요가 있다.
Golang에서 값을 읽어오는 방법은 여러가지가 존재한다.
그 중에 대표적으로 가장 많이 사용되는 2가지는
1. bufio.NewReader의 ReadString
2. bufio.NewScanner의 Scan & Text
를 들 수 있다.
보통 일반적인 경우, Reader에 비해 Scanner가 더 편리하다.
Scanner로 데이터를 읽어들일 경우, '\n'과 같은 개행문자의 제거를 별도로 strings.TrimSuffix() 등을 통해 해줄 필요가 없다.
때문에 Reader에 비해 코드의 가독성이 더 좋은 편이다.
그러나 Scanner 사용 시 주의할 점은, Buffer의 크기가 제한되어 있다는 점이다.
bufio.Scanner를 통해 버퍼가 처음 생성되는 순간, bufio/scan.go에 정의되어 있는 MaxScanTokenSize = 64 * 1024 = 65,536 개의 byte를 담을 수 있도록 생성된다. 때문에 본 문제에서 최대 1,000,000개의 문자열이 입력으로 주어질 경우 문자열을 한 번에 읽어들일 수 없는 곤란한 상황이 발생한다. 따라서 이 경우 bufio.Scanner를 통해 초기 버퍼를 생성 후, sc.Buffer를 통해 버퍼의 사이즈를 변경해야 문제를 풀 수 있다.
한편, bufio.NewReader의 ReadString를 사용하게 되면, 별도의 제한이 없이 한 줄을 그대로 읽어들일 수 있다.
3. 풀이
읽어들일 문자열과 정답을 담을 변수를 정의한다.
var input string
var res int
bufio.NewReader의 ReadString을 통해 주어진 문자열을 읽어들인다.
reader := bufio.NewReader(os.Stdin)
input, _ = reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")
문자열 input을 공백을 기준으로 split하여 string을 원소로 하는 배열 words를 만든다.
이후 배열을 탐색하며 단어의 개수를 센다.
이때 주의할 점은 빈 문자열일 경우는 제외하고 count해야 한다는 점이다.
words := strings.Split(input, " ")
for i := range words {
if words[i] != "" {
res++
}
}
fmt.Println(res)
전체 코드는 다음과 같다.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
var input string
var res int
reader := bufio.NewReader(os.Stdin)
input, _ = reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")
words := strings.Split(input, " ")
for i := range words {
if words[i] != "" {
res++
}
}
fmt.Println(res)
}
한편, bufio.NewScanner를 이용할 경우, 다음과 같이 코드를 작성할 수 있다.
주의할 점은 sc.Buffer를 통해 버퍼의 크기를 주어지는 문자열의 최대 크기인 1,000,000보다 크게 설정하는 것이다.
<Golang 풀이>
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
var res int
var input string
const MaxBuf int = 1000001
sc := bufio.NewScanner(os.Stdin)
sc.Buffer(make([]byte, 0, MaxBuf), MaxBuf) // change sc buffer size to MaxBuf
sc.Scan() // scan one line from os.Stdin
input = sc.Text() // scanned one line into string data
words := strings.Split(input, " ")
for i := range words {
if words[i] != "" {
res++
}
}
fmt.Println(res)
}
백준 1152. 단어의 개수 (브론즈 2)
https://www.acmicpc.net/problem/1152
-문제해결흐름을 간단히 정리한 주관적 포스팅-
-부족한 설명이 있다면 부디 조언 부탁드립니다-
이 포스팅은 쿠팡 파트너스 활동의 일환으로,
이에 따른 일정액의 수수료를 제공받습니다
'IT > Algorithm' 카테고리의 다른 글
Leetcode 1. Two Sum - Dart, Python (84) | 2023.02.27 |
---|---|
백준 1157. 단어 공부 - Golang, Python (8) | 2023.02.06 |
Leetcode 5. Longest Palindromic Substring - Python (cf. 백준 13275) (2) | 2022.12.15 |
Leetcode 33. Search in Rotated Sorted Array - Python (0) | 2022.07.25 |
Leetcode 647. Palindromic Substrings - Python (0) | 2022.07.21 |