from collections import Counter s = input().upper() #단어를 입력받고 대문자로 바꿔서 s에 저장해 준다. if len(s) == 1: print(s) #단어의 길이가 1이면 최빈 문자가 1개 뿐이므로 그냥 그 단어 출력 elif Counter(s).most_common(2)[0][1] == Counter(s).most_common(2)[1][1]: print('?') else: print(Counter(s).most_common(1)[0][0])
이 문제는 그냥 dictionary나 리스트로 그 값의 빈도 수를 저장해서 풀이하면 된다.
그러나 '리스트나 문자열 등에서 최빈값을 찾아내 주는 함수가 있지 않을까?' 라는 호기심에 구글링을 해봤고 역시나 있었다! 참고 사이트(클릭)
collections
라는 모듈에서 Counter
라는 함수로 최빈값을 찾을 수 있었다.
Counter(s)
를 해주면 다음과 같다.
>>> from collections import Counter
>>> a = 'abbcccddddeeeee'
>>> Counter(a)
Counter({'e': 5, 'd': 4, 'c': 3, 'b': 2, 'a': 1})
>>> type(Counter(a))
<class 'collections.Counter'>
최빈값의 빈도수를 기준으로 내림차순으로 정렬 된 dictionary 형태의 모양으로 출력된다. 클래스 이름은 collections.Counter
라고 한다...
그 다음 most_common()
함수는 ( )안의 수 만큼 최빈값과 그 값의 빈도수를 튜플 형태로 만들어서 리스트로 묶어서 리턴해 준다.
>>> mode = Counter(a)
>>> mode.most_common(2)
[('e', 5), ('d', 4)]
>>> mode.most_common(4)
[('e', 5), ('d', 4), ('c', 3), ('b', 2)]
>>>
쉽게 얘기해서 2등까지 보여달라!, 4등까지 보여달라! 이런 셈이다.
최빈값에 접근하고 싶으면 mode.most_common(1)[0][0]
이렇게 입력하면 된다.
따라서 문제로 돌아가 보면,
#include <string> #include <iostream> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); string S; cin >> S; for (int i = 0; i < S.size(); i++) { S[i] = toupper(S[i]); //단어를 전부 대문자로 변환 } int alpha[26] = { 0, }; //크기가 26인 배열 생성 for (char a : S) { //단어 S의 각 문자를 돌며 그 문자의 번호를 인덱스로 해서 빈도수를 1씩 늘려준다. //A = 0, B = 1, ..., Z = 25 alpha[a - 65]++; } //최빈값 찾기 int max = -1; int cnt = 0; for (auto i : alpha) { if (max < i) max = i; } //최빈값 개수 찾기 for (int i = 0; i < 26;i++) { if (alpha[i] == max) cnt++; if (cnt >= 2) { cout << "?"; return 0; //최빈값 개수가 2개 이상이면 main함수 끝냄 (더이상 실행 안함) } } for (int i = 0; i < 26; i++) { if (alpha[i] == max) cout << (char)(i + 65); //최빈값 출력 } }