코딩 문제

백준 2108, 10816 - collections모듈 Counter 클래스 사용법

토리쟁이 2022. 8. 5. 03:22

collections 라이브러리 Counter함수는 데이터의 개수를 셀 때 유용하게 사용되는 함수이다.

원소의 갯수가 많지 않은 리스트의 경우, 내장함수인 count()를 사용하여 간단하게 구할 수 있지만

원소의 갯수가 많을 경우에는 매우 시간이 오래걸린다는 단점이 있다.

collections 모듈의 Counter클래스를 사용하면 짧은 시간에 데이터의 개수를 구할 수 있다.

직접 사용해보자.

from collections import Counter

collections 모듈로부터 Counter을 임포트해서 사용하면 된다.

위의 사진은 문자열 'hello world'에 Counter을 사용한 결과이다.

이처럼 각 데이터에 대하여 {데이터:데이터 개수}의 딕셔너리 형태로 결과값을 반환한다.

 

Counter클래스는 데이터의 개수가 많은 순으로 정렬된 리스트를 리턴하는 most_common() 메소드도 제공한다.

cnt에 most_common() 함수를 적용한 결과이다.

데이터의 개수를 기준으로 내림차순 정렬된 리스트 값을 반환한다.

 

이를 활용하여 백준 2180번을 풀어보자

 

나의 풀이)

그냥 시간 복잡도 생각안하고 냅다 구현해버림

테스트케이스 결과값은 제대로 나왔지만, 백준에서 시간초과로 실패하였다.

아래 코드는 내가 시도한 코드이다.

import sys
n = int(input())
l=[]
for i in range(n):
    l.append(int(sys.stdin.readline()))
length = len(l)
avg=sum(l)/length
index=length//2
l.sort()
middle=l[index]
r=abs(l[-1]-l[0])

s=list(set(l))
a={i: l.count(i) for i in s}
v=list(a.values())
k=list(a.keys())
m=max(v)
if v.count(m)==1:
    index=v.index(m)
    many=k[index]
else:
    manys = [k[i] for i, value in enumerate(v) if value==m]
    manys.sort()
    many=manys[1]
print(round(avg))
print(middle)
print(many)
print(r)

리스트의 원소들을 줄여보고자 집합으로 바꾸기까지 했는데 

각 원소들을 count하는 과정에서 시간초과가 발생한 것 같다.

이를 해결하기 위하여 위에서 학습한 Counter을 이용하여 다시 풀었다.

 

from collections import Counter
import sys
n = int(input())
l=[]
for i in range(n):
    l.append(int(sys.stdin.readline()))
length = len(l)
avg=sum(l)/length
index=length//2
l.sort()
middle=l[index]
r=abs(l[-1]-l[0])

cnt=Counter(l).most_common()
if len(l)==1:
    many=l[0]
else:
    if cnt[0][1]==cnt[1][1]:
        many = cnt[0][0] if cnt[0][0]> cnt[1][0] else cnt[1][0]
    else:
        many=cnt[0][0]

print(round(avg))
print(middle)
print(many)
print(r)

만약 최빈값이 2개 이상일 경우, 두번째로 작은 값을 최빈값으로 한다는 조건을 만족시키기 위해서

조건문을 추가로 작성하였다.

+ 입력값이 하나만 들어왔을 경우, 입력된 숫자가 최빈값이라는 조건도 추가하였다.

 

 

 

백준 10816도 해당 클래스를 활용하여 문제 풀이가 가능하다.

이 문제도 되게 간단한 문제인데 답은 잘 나오지만, 시간 초과가 났었다.

해당 클래스를 활용해서 풀었더니 해결되었다.

 

 

from collections import Counter
import sys
n=int(input())
a=sys.stdin.readline().split()
m=int(input())
b=sys.stdin.readline().split()

cnt=Counter(a)
for i in b:
    print(cnt[i], end=" ")

'코딩 문제' 카테고리의 다른 글

백준 11051 - 이항 계수2  (0) 2022.10.07
백준 2981 - 검문  (0) 2022.09.22
백준 18870 - 좌표압축  (0) 2022.08.04
백준 - 단어정렬 (조건이 있는 정렬)  (0) 2022.07.21
백준 골드바흐의 추측  (0) 2022.07.12