자기계발
백준
1157 · 단어 공부 (2023)

백준 1157번 단어 공부

문제

알파벳 대소문자로 된 단어(길이 1,000,000 이하)가 주어진다. 대소문자를 구분하지 않고 가장 많이 사용된 알파벳을 대문자로 출력하고, 가장 많이 사용된 알파벳이 여러 개면 ?를 출력한다.

풀이

시간 초과 때문에 여러 번 고친 문제다. 단어를 대문자로 바꾼 뒤 문자별 개수를 딕셔너리에 담고, 개수 기준 내림차순으로 정렬해 1등과 2등의 개수를 비교한다. 두 값이 다르면 1등 문자를, 같으면 ?를 출력한다.

시간을 줄이려고 한 시도는 다음과 같다.

  • 단어의 모든 글자를 돌며 매번 딕셔너리 값을 갱신하지 않고, 아직 키에 없는 문자일 때만 개수를 센다.
  • collections의 Counter로 먼저 풀었지만 통과하지 못했고 이유는 확인하지 못했다.
  • input()을 sys.stdin.readline으로 바꾸는 것도 시도했다.
def get_counter():
    text = input().upper()
    cnt = dict()
 
    for t in text:
        if t not in cnt.keys():
            cnt[t] = text.count(t)
 
    c = sorted(cnt.items(), key=lambda x: x[1], reverse=True)
    
    if len(c) == 1:
        print(text)
    elif c[0][1] != c[1][1]:
        return print(c[0][0])
    else:
        return print('?')
 
get_counter()

이 코드는 단어가 한 종류의 알파벳으로만 이루어졌고 길이가 2 이상인 경우(예: zzz)에 틀린다. len(c) == 1 분기에서 알파벳 하나가 아니라 대문자로 바꾼 단어 전체(ZZZ)를 출력하기 때문이다. 길이가 1인 입력에서는 우연히 맞는다.

짚고 갈 점

  • 효율적인 코드를 짜는 것은 아직 부족하다. 데이터 처리 파이프라인을 구축할 때도 비슷하게 고민할 부분이다.

출처