2023. 2. 6. 21:00ㆍIT/Algorithm
1. 문제 이해하기
알파벳 대소문자로 된 단어가 주어진다.
이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력하라.
단, 가장 많이 사용된 알파벳이 여러 개일 경우, ?를 출력하라.
(단어의 길이는 1,000,000 이하)
2. 아이디어 구상
간단한 문제다.
주어진 단어를 탐색하며 각 알파벳이 몇 개인지 세고 가장 많이 등장한 알파벳을 리턴하면 된다.
Python으로 풀 경우 collections 모듈의 Counter를 이용하면 주어진 String에서 가장 많이 출현한 character를 쉽게 얻을 수 있다.
input으로 단어를 받아 모든 알파벳을 대문자로 변환한 후, most_common()을 통해 최빈출 알파벳을 구한다.
만약 알파벳이 여러 개면 ?를 리턴해준다.
<Python 풀이>
from collections import Counter
import sys
input = lambda : sys.stdin.readline().strip()
word = input().upper()
res = Counter(word).most_common()
if len(res) == 1:
print(res[0][0])
elif res[0][1] == res[1][1]:
print("?")
else:
print(res[0][0])
Golang으로 풀 경우에도 비슷하다.
다만 Counter 같은 편리한 도구가 아직 Golang에는 없기 때문에 우리가 직접 구현해야 한다.
구현은 어렵지 않다. Map을 통해 쉽게 할 수 있다.
Python의 Counter 또한 사실 내부를 들여다 보면 dictionary, 즉 map을 상속받아 구현되어 있다.
3. 풀이
읽어들일 문자열 input과 정답 res, 그리고 가장 큰 반복횟수를 담을 maxVal 를 정의한다.
var input, res string
var maxVal int
bufio.NewReader의 ReadString을 통해 주어진 문자열을 읽어들이고, strings.ToUpper를 통해 전체 character를 대문자로 만든다.
reader := bufio.NewReader(os.Stdin)
input, _ = reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")
input = strings.ToUpper(input)
등장하는 character를 key로, 출현빈도수를 value로 하는 map을 선언하고 단어를 탐색하며 빈도를 map에 기록한다.
이때 주어진 단어 input을 for문으로 탐색할 경우, 그 값은 아스키 코드가 된다.
때문에 string(c)로 형변환을 해야 map의 key값으로 출현한 알파벳이 들어간다.
counter := make(map[string]int)
for _, c := range input {
if string(c) != " " {
counter[string(c)]++
}
}
Map을 탐색하며 maxVal와 res를 업데이트한다.
위 파이썬 코드와 동일한 로직이다.
for character, occurrence := range counter {
if occurrence > maxVal {
maxVal = occurrence
res = string(character)
} else if occurrence == maxVal {
res = "?"
}
}
전체 코드는 다음과 같다.
<Golang 풀이>
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
var input, res string
var maxVal int
reader := bufio.NewReader(os.Stdin)
input, _ = reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")
input = strings.ToUpper(input)
counter := make(map[string]int)
for _, c := range input {
// fmt.Println(reflect.TypeOf(c))
// fmt.Println(c) -> return ASCII
// fmt.Printf("%v", string(c))
if string(c) != " " {
counter[string(c)]++
}
}
for character, occurrence := range counter {
if occurrence > maxVal {
maxVal = occurrence
res = string(character)
} else if occurrence == maxVal {
res = "?"
}
}
fmt.Println(res)
}
Golang으로 String을 자주 다루는 업무를 하게 된다면, Python의 Counter처럼 편안한 기능이 있는 라이브러리를 구축할 필요가 있겠다.
위와 같이 Map으로 구현할 수도 있겠고, Golang의 container/heap을 이용해 Counter의 function들을 구현할 수도 있겠다.
Golang으로 Python의 collections.Counter 구현하기
백준 1157. 단어 공부 (브론즈 1)
https://www.acmicpc.net/problem/1157
-문제해결흐름을 간단히 정리한 주관적 포스팅-
-부족한 설명이 있다면 부디 조언 부탁드립니다-
이 포스팅은 쿠팡 파트너스 활동의 일환으로,
이에 따른 일정액의 수수료를 제공받습니다
'IT > Algorithm' 카테고리의 다른 글
백준 1546. 평균 - Golang, Python (89) | 2023.04.03 |
---|---|
Leetcode 1. Two Sum - Dart, Python (84) | 2023.02.27 |
백준 1152. 단어의 개수 - Golang, Python (2) | 2023.01.30 |
Leetcode 5. Longest Palindromic Substring - Python (cf. 백준 13275) (2) | 2022.12.15 |
Leetcode 33. Search in Rotated Sorted Array - Python (0) | 2022.07.25 |