본문 바로가기
DEV/백준 알고리즘

백준 알고리즘 1157번(파이썬)

by 올커 2022. 10. 7.

 

백준 1157번_파이썬 알고리즘

Q. 백준 1157. 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.
(1) 입력 : 첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.

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


A. 풀이

 - 해당 문제는 딕셔너리를 사용하여 풀이하게 되면서 코드가 길고 복잡해졌다. 

 

# Q 백준 1157. 단어 공부 ★★★★★
alpha_str = input().upper()
dict_alpha = {} #딕셔너리 선언

# 입력받은 문자열 리스트 생성
cnt_model = list(alpha_str)

# key로 각 문자를, value로 0을 가진 딕셔너리 생성
dict_alpha = dict.fromkeys(cnt_model, 0)

# 각 문자의 수를 count하여 딕셔너리 value에 입력
for i in range(len(cnt_model)):
    dict_alpha[cnt_model[i]] += 1


# 최대값 넣을 리스트 생성
list_alpha = []

# 리스트에 value를 최대로 가진 key 추가
for key, value in dict_alpha.items():
    if value == max(dict_alpha.values()):
        list_alpha.append(key)

if len(list_alpha) == 1:    # 리스트에 추가된 값이 하나라면
    print(list_alpha[0])    # key값 출력
else:                       # 리스트에 추가된 값이 여러개라면
    print('?')              # '?' 출력

 

1) 변수 선언부

 - 딕셔너리 선언은 변수명 = {} 으로 간단하게 해줄 수 있다.

 - 딕셔너리에 key만 넣고 초기값을 지정해주고 싶을 경우에는 일일이 지정해주는 방법도 있지만, 'dict.fromkeys(리스트명, value로 넣을 값)'를 사용하여 한문장으로 해결할 수 있었다.

 

2) 반복문(for문) (1)

 - 입력받은 각 문자의 수를 카운트하기 위해 for 문을 사용하였다.

 

 - 이 중 최대값은 따로 관리하기 위해 list_alpha라는 리스트를 새로 생성하였다.

 

3) 반복문(for문) (2)

 - 딕셔너리 내부의 key와 value를 모두 가져오기 위해서 '딕셔너리명.items()'를 for문에서 사용하였다.

 - for문을 돌면서 최대값일 경우 list에 넣기 위해 조건문 if를 사용하였다.

 

4) 조건문(if문)

 - 마지막 조건문은 검사를 위해 생성하였다.

 - 최대값을 뽑아낸 리스트는 값이 하나라면 값을 출력하여도 되지만, 문제에서 값이 2개이상일 경우 '?'를 출력하라고 하였으므로, 동일한 최대값이 존재한다면 리스트에서 값이 2개 이상이기 때문에 else문이 출력된다.


# Q 백준 1157 다른 풀이
w = input().upper()
w_set = list(set(w))	# 알파벳 담는 리스트
cnt = []		# 알파벳이 등장한 횟수를 담는 리스트

for i in w_set:
    cnt.append(w.count(i))	# 등장한 횟수 차례차례 담아주기

if cnt.count(max(cnt)) >1:	# max 값이 몇 번 등장했는지 확인
    print('?')
else : 
    cnt_max_id = cnt.index(max(cnt))
    print(w_set[cnt_max_id])

 - 두 번째 코드는 리스트를 사용한 결과이다.

 - 딕셔너리를 사용할 때 보다 코드가 훨씬 간결해진 모습이다.

 

1) 변수 선언부

 - 입력받은 문자열의 각각의 알파벳을 set()으로 중복을 제거한 후 list()를 통해 리스트에 담고, 등장한 횟수는 cnt라는 리스트에 요소로 들어간다.

 

2) 반복문(for문)

 - 각 알파벳이 등장한 횟수는 '문자열.count(해당문자)' 를 사용했다. 이때 for문을 돌리기 위해 각 문자열을 사전에 리스트에 넣어주었던 것이다. 이를 통해 리스트 cnt에 w_set의 리스트 인덱싱 순서로 값이 들어가게 된다.

 

3) 조건문(if문)

 - max(cnt)의 갯수를 cnt에서 세었을 때 1보다 크다면 최대값을 동일하게 가진 문자가 2개이상이라는 것이기 때문에 '?' 출력을 한다. 그렇지 않을 경우 최대값을 출력한다.


R. 리뷰

 - 문제의 출력에 집중을 하면 예상외로 간단한 풀이방법이 나온다.

 - 사실, key와 value라는 관점으로 '특정 문자가 나타난 수는 그 문자와 항상 연결되어있어야 한다' 라는 생각 때문에 딕셔너리를 쓴 것이지만, 크게 복잡하지 않은 문제에서는 간단히 인덱싱이 같은 리스트를 두 개 만들어서 공유하면 되기 때문이다.

 - 그러나 문제가 더 복잡해지거나 하면, 인덱싱으로는 연결이 약할 수 있다는 생각도 한편으로 들었다.

반응형

댓글