Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Joon's Space

[Python] 백준 알고리즘 #2108 통계학 본문

Algorithm/baekjoon

[Python] 백준 알고리즘 #2108 통계학

Happy Joon 2021. 1. 18. 07:34

문제풀이 

 

이 문제는 N개만큼 입력받은 수의 산술평균, 중앙값, 최빈값, 범위를 출력하는 구현 문제이다. 

 

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값

  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값

  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값

  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

다음과 같이 구현하면 되겠다. 

중앙값, 범위를 구할 때 쉽게 접근하기 위해서 먼저 입력받은 값들의 리스트를 생성한 뒤, sorted 함수로 정렬해준다. 

 

산술평균 -> sum 함수를 이용해서 리스트 길이만큼 나누어주고 round 함수로 반올림해준다. 중앙값 -> N의 갯수는 홀수이기 때문에 길이의 2로 나눈 값이 중앙값이 되겠다.최빈값 -> '수정렬하기3' 문제에서 배웠던 계수 정렬(Count Sort)을 이용한다.범위 -> 리스트 첫번째와 마지막을 뺀 값을 출력해준다. 

 

import sys
input = sys.stdin.readline

N = int(input())
result = []
for i in range(N):
    result.append(int(input()))

result = sorted(result)
#print(result)
print(round(sum(result)/len(result))) #산술평균
print(result[len(result)//2]) #중간값

counter = [0 for i in range(8001)]

for i in result:
    counter[i+4000] += 1

if N <= 1:
    print(result[0])

elif counter.index(max(counter)) == counter.index(max(counter), counter.index(max(counter))+1 , len(counter)):
    print(counter.index(max(counter))-4000) #최빈값
else:
    print(counter.index(max(counter), counter.index(max(counter))+1 , len(counter))-4000)

print(result[len(result)-1]-result[0]) #범위

여기서 처음에 당황한게 입력받은 값이 음수일 때를 고려하지 않았지만, 절댓값을 4000을 넘지 않으므로 , -4000~4000까지 8001 길이의 0이 가득 찬 리스트를 생성 후 count sort 해준다. 

 

여기서 주의할 점은, 최빈값은 여러 개 있을 때 최빈값 중 두번 째로 작은 값을 출력해야 한다. counter리스트에서 max값을 갖는 인덱스를 반환해야 하는데, index함수에서는 가장 왼쪽의 인덱스의 값을 출력하므로 index(max값, max+1, len(counter)) 을 이용해서 max+1 번째부터 max 값을 갖는 인덱스 번호를 구한다. 

 

이렇게 모두 구현한 후, 제출을 했지만 

다음과 같은 에러가 나왔다. 입출력 예시와 똑같이 나오지만 내가 간과한점들이 있었나 보다. 런타임 오류가 나는 이유는, 다른 사람들의 해결을 보던 중 

 

문제들을 찾던중, collection 모듈의 Counter 클래스를 사용하면 계수 정렬을 이용하는 것보다 훨씬 더 쉽게 최빈값을 찾는 것이 가능했다. 

 

counter 클래스의 사용법은 다음 글을 참조하였다.

www.daleseo.com/python-collections-counter/

 

[파이썬] collections 모듈의 Counter 클래스 사용법

Engineering Blog by Dale Seo

www.daleseo.com

 

입력받은 숫자들의 리스트를 Counter 클래스를 사용하면, 받은 숫자들의 Counting 한 값을 딕셔너리 값으로 리턴하여 준다. 

 

여기서 Counter 클래스의 most_common() 함수를 이용하면, 가장 많이 counting 된 값을 리턴하여 주는데 여기서 좋은 점은 가장 많이 counting 된 값이 여러 개 있을 경우 index함수처럼 가장 왼쪽 하나만 출력되는 것이 아니라 여러 개 값을 모두 리턴해준다. 

 

import sys
from collections import Counter

input = sys.stdin.readline

N = int(input())
result = []
for i in range(N):
    result.append(int(input()))

result = sorted(result)
#print(result)
print(round(sum(result)/len(result))) #산술평균
print(result[len(result)//2]) #중간값

#print(Counter(result).most_common())

frequency = Counter(result).most_common()

if len(result) > 1:
    if frequency[0][1] == frequency[1][1]:
        print(frequency[1][0]) #최빈값
    else:
        print(frequency[0][0])
else:
    print(result[0])
print(result[len(result)-1]-result[0]) #범위

 

이번 문제를 통해서 새로운 Counter 클래스의 기능을 알게 되었다. 다른 문제에서도 적용하면 쉽게 풀리는 문제들도 많을 것 같다.

 

www.acmicpc.net/problem/2108

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

 

반응형