백준 1157. 단어 공부 - Golang, Python

2023. 2. 6. 21:00IT/Algorithm

반응형

백준 1157 문제 보기

 

1. 문제 이해하기

알파벳 대소문자로 된 단어가 주어진다.

이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력하라.

단, 가장 많이 사용된 알파벳이 여러 개일 경우, ?를 출력하라.

(단어의 길이는 1,000,000 이하)

 

2. 아이디어 구상

간단한 문제다.

주어진 단어를 탐색하며 각 알파벳이 몇 개인지 세고 가장 많이 등장한 알파벳을 리턴하면 된다.

 

By Mesotes

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

 

 

 

 

-문제해결흐름을 간단히 정리한 주관적 포스팅-

 

-부족한 설명이 있다면 부디 조언 부탁드립니다-

 

 

 

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로,

이에 따른 일정액의 수수료를 제공받습니다

반응형