문제링크
문제
알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.
입력
첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.
출력
첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 "?" 를 출력한다.
예제 입력
Mississipi
예제 출력
?ㅤ
예제 입력
zZa
예제 출력
Zㅤ
예제 입력
zㅤ
예제 출력
Zㅤ
예제 입력
baaa
예제 출력
Aㅤ
풀이
문제 이해
문제를 정리하자면 대소문자가 섞여있는 문자열을 입력받게 됩니다
그리고 대소문자 구분 없이 가장 많이 사용된 문자를 찾아내면 됩니다
단 출력은 대문자로 해야 된다고 나와 있기 때문에 결국에는 입력받은 문자열을 모두 대문자로 바꾼 후 가장 많이 사용된 문자를 찾아내면 됩니다
예를 들어서 A와 B가 각각 3개씩 문자 열중 가장 많이 사용되어서 동일 알파벳이 2개 이상인 경우에는?를 출력해주면 됩니다
코드설명 1
결론부터 말씀드리자면 해당 코드는 시간초과로 인해 백준 문제 제출 시 오답처리가 되었습니다 제가 작성하여 시도해본 코드 중 첫 번째는 딕셔너리를 이용한 방법입니다
아래는 전체 코드입니다
1
2
3
4
5
6
7
8
9
10
11
12
13
|
s = input().upper()
liss ={}
for j in s:
for i in range(65,91):
if s.count(chr(i)) >= 2:
liss[chr(i)] = s.count(chr(i))
al= [k for k,v in liss.items() if max(liss.values()) == v]
if len(al) >= 2:
print('?')
else:
max_key = max(liss, key=liss.get)
print(max_key)
|
cs |
이제 코드를 하나씩 나누어서 함께 알아보겠습니다
#1 먼저 입력받는 문자열을 대문자로 바꿔서 저장시키기 위해 upper() 함수를 사용하였고
#3~#6 이중 반복문으로 첫 번째 j부터 s(문자열의 개수)만큼 반복해주면서 두 번째 i부터 (65~91)까지의 범위(아스키코드 A~Z)만큼 반복하면서 입력받은 문자열에 A~Z까지 일치하는 값이 있나 찾으면서 만약 2개 이상 일치하는 값이 있을 경우 {'일치하는 알파벳': '갯수'} 형태로 liss 딕셔너리에 저장됩니다
#8 코드는 max() 함수를 이용하여 딕셔너리 값 중 반복된 횟수가 가장 많은걸 찾으면 되는데 max함수를 사용할 때 만약 딕셔너리 Value의 최댓값이 여러 개일 때는 가장 앞에있는 Key하나만 출력해주기 때문에 Value의 최대값이 여러개일때는 리스트 컴프리핸션을 이용하면 됩니다
al= [k for k,v in liss.items() if max(liss.values()) == v]
#9~#10 al변수에 최댓값 liss변수의 key(알파벳)들이 담기게 되며 len() 함수로 al변수에 담긴 알파벳 개수를 구한 후 만약 알파벳의 개수가 2개 이상이면 가장 많이 사용한 알파벳이 여러 개이기 때문에 '?'를 출력해줍니다
#11~#13 if조건문에 맞지 않는다면 else 쪽으로 빠지면서 liss딕셔너리 key 중 가장 많이 사용된 value의 key 알파벳을 가져온 뒤에 출력해주면 됩니다
위의 코드로 문제 페이지에 있는 예제의 입출력을 돌려봤는데 정상적인 결과는 나오지만 Backjoon에서는 시간 초과로 오답처리가 된다 그래서 딕셔너리가 아닌 다른 방법으로 코드를 작성해보았습니다
코드 설명2 - 단시간 해결
1
2
3
4
5
6
7
8
9
10
|
s = input().upper()
liss=[]
for i in range(65,91):
liss.append(s.count(chr(i)))
if(liss.count(max(liss)) > 1):
print('?')
else:
ascii = int((liss.index(max(liss))))
print(chr(65+ascii))
|
cs |
두 번째로 작성한 코드는 딕셔너리가 아니라 리스트를 활용한 방법입니다
각 코드별로 자세히 살펴보겠습니다
#1은 이전 코드와 동일하게 사용자로부터 문자열을 받아 저장합니다
이때 모든 문자는 upper()함수로 대문자로 변환하여 저장합니다
#3~#4 반복문을 사용하여 65~91까지 반복하며 liss함수에 65부터 91까지 즉 A부터 Z까지의 각 해당하는 문자의 개수를 순서대로 저장해줍니다 총 리스트는 A부터 Z까지 26개의 값이 들어가는셈입니다
#5~#10 if조건문을 사용하여 liss리스트에 저장된 내용을 토대로 가장 많이 사용된 알파벳이 몇 개인지를 구하고 만약 가장 많이 사용된 알파벳의 개수가 1개보다 많으면 여러 개 이기 때문에?를 출력해줍니다
#8~#10 만약 위 조건과 맞지 않을 경우엔 liss리스트에 저장된 값들 중 가장 큰 값의 위치를 선택하여 ascii변수에 저장합니다
예를 들어 B를 가장 많이 사용할 경우에는 두 번째인 1이 저장되고 F가 가장 많이 사용되었을 경우 알파벳순으로 정수 5가 저장되게 됩니다
결국에 출력할 때는 아스키코드로 변환하여 A의 아스키코드인 65를 기준으로 A일 경우 0을 더해서 A를 출력해주고
C일 경우 65에 2를 더해서 67의 아스키코드 C를 출력해줍니다
문제 제출 결과 92ms시간이 걸렸으며 코드 길이는 203B로 꽤 빠른 속도와 적은 양의 코드 길이로 문제를 풀었습니다!