본문 바로가기
Algorithm/baekjoon

[백준] 1157번 단어 공부 파이썬 (python)

by eoieiie 2024. 3. 13.

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net

 

문제

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

 

입력

첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.

 

출력

첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

 

정답코드

word = input().upper()
word_list = list(set(word))

cnt = []
for i in word_list:
  count = word.count(i)
  cnt.append(count)

if cnt.count(max(cnt)) > 1:
  print("?")

else:
  print(word_list[(cnt.index(max(cnt)))])

 

풀이

  1. 입력받은 단어를 대문자로 바꿔 word에 저장한다. 
  2. word_list를 선언하고 입력받은 word에서 set함수를 이용하여 중복되는 항목을 제거하여 넣어준다.
  3. 리스트 cnt를 선언한다. 
  4. word_list 중에서 차례대로 하나씩 가져와서,
  5. count라는 변수에다가 count() 함수를 사용하여 가져온 값의 word안에서의 총 출현 횟수를 저장하고, 
  6. cnt안에다가 그 저장한 값을 추가해준다.
  7. 만약 cnt안의 최댓값의 개수가 1보다 많다면 "?" 를 출력하고 
  8. 만약 그렇지 않다면 (1개만 존재한다면) 
  9. word_list 안에서 cnt의 최댓값의 인덱스와 동일한 위치의 값을 출력한다.

 

느낀 점

개인적으로는 브론즈 문제 중 가장 재밌고 보람찼던 문제였다. 아마 단계별로 풀어보기에서는 이 문제 다음 실버 문제들이 스멀스멀 올라오는 것으로 알고 있는데, 여전히 별 이상한 방법 다 끌어모아서 만들긴 했지만 결과적으로 많은 것들을 배웠다는 것에, 그리고 큰 틀에서 바라본 로직의 구현이 정답코드와 동일하다는 점에서 의의를 두었다.  내가 제출한 코드는 아래와 같다.

 

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        
word = input().upper()

cnta = 0
for n in alphabet:
    if n in word:
        cnta += 1

lista = [0] * cnta

listb = []
cntb = 0 

for n in alphabet:
    if n in word:
        listb.append(n)
        for m in word:
            if n == m and n not in lista:
                lista[cntb] += 1
        cntb += 1

maxvalue = 0

for i in lista:
    if i > maxvalue:
        maxvalue = i


cntc = 0

for i in lista:
    if i == maxvalue:
        cntc += 1

if cntc == 1:
    print(listb[lista.index(maxvalue)])
else:
    print("?")

 

 

우선 알파벳을 담을 변수 alphabet을 선언해 준다.

 

  1. 단어를 입력받고, 대문자로 미리 변경하여 저장한다. 
  2. 일단 lista의 길이를 정해주기 위해서 아래와 같은 과정을 거친다. lista는 추후 각 단어의 출현 횟수를 저장할 리스트이다:
  3. cnta 변수를 지정한다.
  4. 알파벳의 각 단어를 가져와서, 
  5. 만약 그 단어가 입력받은 word안에 존재한다면 
  6. cnta를 1씩 증가시킨다. (하나가 있어도, 여러 개가 있어도 1만 증가시킨다.)
  7. 증가한 최종 cnta만큼 lista의 길이를 지정해 준다. 이는 단어 안의 알파벳의 종류의 개수를 셀 수 있게 해 준다. 

 

그다음에는 새로운 listb를 만든다.

 

  1. listb는 추후 단어 안의 글자의 종류를 차례대로 저장할 리스트이다. 
  2. cntb 변수를 지정한다. 이는 for문이 돌 때마다 1씩 증가할 변수이다. 
  3. 이제 알파벳들을 a부터 차례대로 가져올 건데,
  4. 가져온 알파벳이 word안에 있다면
  5. 그 알파벳 n을 listb안에 넣어준다. 
  6. 넣은 다음 lista를 증가시키는데,
  7. 일단 word에서 첫 글자부터 차례대로 가져온다
  8. 가져온 글자가 listab안에 들어간 알파벳 n과 동일하다면,
  9. lista의 cntb-1번째 인덱스의 값을 1 증가시킨다. 
  10. 이렇게 해서 최종적으로 lista안에는 글자의 개수가, 
  11. listab안에는 글자의 종류가 들어가며
  12. 리스트의 각 요소(글자의 종류와 글자의 개수)의 인덱스는 동일하게 설정되었다.

 

 그다음으로는 글자의 개수와, 중복 여부를 판별해 보았다.

 

  1. maxvalue를 선언한다. 
  2. lista의 각 숫자를 가져와서 
  3. maxvalue와 비교하며 lista의 maxvalue를 찾는다.
  4. cntc를 선언한다. 이는 lista 내부 maxvalue의 개수를 판별할 변수가 된다. 
  5. lista의 각 요소를 돌면서 maxvalue와 일치하는 숫자가 있다면 cntc를 증가시킨다. 
  6. 이제 출력을 해주자. 만약 cntc가 하나만 존재한다면(maxvalue가 하나만 존재한다면)
  7. lista 안에서 maxvalue가 존재하는 인덱스의 동일 인덱스로 listb에서 글자를 뽑아 출력하고
  8. 만역 cntc가 여러 개라면
  9. "?"를 출력하라!
  10. 끝어휴드디어

재밌다. 아주 재밌다. 

set 함수를 사용했다면 더 편하게 풀 수 있었을 거라고 생각한다.

 

댓글