출처 | https://www.acmicpc.net/problem/2108
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
산술평균 : N개의 수들의 합을 N으로 나눈 값
중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
최빈값 : N개의 수들 중 가장 많이 나타나는 값
범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.
#include <stdio.h>
#include <math.h>
int arith_mean(int* arr, int N);
int median(int* counting, int N);
int mode(int* counting, int N);
int range(int* counting, int N);
int main(void) {
int N;
scanf_s("%d", &N);
int arr[N];
for (int i = 0; i < N; i++) {
scanf("%d", &arr[i]);
}
//정렬(카운팅 정렬)
int counting[8001]; //0~8000이 -4000~+4000을 의미
for (int i = 0; i < 8001; i++) {
counting[i] = 0;
}
for (int i = 0; i < N; i++) {
counting[arr[i] + 4000]++; //0~8000 -> -4000~4000
}
//각 통계값 출력
printf("%d\n", arith_mean(arr, N));
printf("%d\n", median(counting, N));
printf("%d\n", mode(counting, N));
printf("%d\n", range(counting, N));
}
int arith_mean(int* arr, int N) { //산술 평균
double sum = 0;
for (int i = 0; i < N; i++) {
sum += arr[i];
}
return (int)round(sum / N);
}
int median(int* counting, int N) { //중앙값
// N은 홀수: (N+1)/2 번째 수가 중앙값
int num = 0;
for (int i = 0; i < 8001; i++) {
num += counting[i];
if (num >= (N + 1) / 2) {
return i - 4000;
}
}
return 0;
}
int mode(int* counting, int N) { //최빈값
//counting 값이 가장 큰 값
int max = 0; //가장 높은 빈도
int num = 0; //최빈값의 개수
int mode = 0; //최빈값
for (int i = 0; i < 8001; i++) {
if (counting[i] > max) {
max = counting[i];
num = 1;
mode = i - 4000;
}
else if (counting[i] == max) {
if (num == 1) {
num++;
mode = i - 4000;
}
else { //이미 2개 이상의 최빈값
num++;
}
}
}
return mode;
}
int range(int* counting, int N) { //범위
int max = 0;
int min = 0;
for (int i = 8000; i >= 0; i--) {
if (counting[i] != 0) {
max = i;
break;
}
}
for (int i = 0; i < 8001; i++) {
if (counting[i] != 0) {
min = i;
break;
}
}
return max - min;
}