[백준 2108] 통계학
백준 2108번 - 통계학
❓ 문제
수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
✏️ 풀이
이 문제에서 제일 어려웠고 시간을 많이 썼던 부분은 최빈값을 구하는 부분이었다.
나머지는 수학적 공식으로 쉽게 풀 수 있으니 언급하지 않겠다.
우선, 나는 최빈값에 대해 이렇게 생각하였다.
- map<int, int> 형식으로 key 값에 대해 빈도수를 value로 주기로 결정.
- 중복되는 수는 map.find(key)로 검색을 하여 존재한다면 value++를 함.
- 그리고 이렇게 만들어진 map을 vector<pair<int, int»에 넣음.
- pair->second 값으로 sorting
- 그 후, 빈도수의 max값과 같은 빈도수를 가진 숫자들을 모두 vector에 넣음.
- 위의 vector를 sort한 뒤, 두 번째로 작은 값을 출력.
위 과정들을 아래와 같이 구현하였다.
for (int i=0; i<N; i++) {
int temp;
cin >> temp;
sum+= temp;
num.push_back(temp);
auto iter = mode_map.find(temp);
if (iter != mode_map.end())
iter->second++;
else
mode_map.insert(make_pair(temp,1));
}
cout << mode();
int mode() {
vector<pair<int, int>> mode_vector(mode_map.begin(), mode_map.end());
sort(mode_vector.begin(), mode_vector.end(), compare);
int max_value = mode_vector[mode_vector.size()-1].second;
int count=mode_vector.size()-1;
vector<int> result;
while(1) {
if (count == -1)
break;
if (mode_vector[count].second == max_value) // 빈도수 같은 것들만 넣음
result.push_back(mode_vector[count].first);
count--;
}
sort(result.begin(), result.end());
return (result.size() == 1) ? result[0] : result[1];
}
다소 복잡한 과정으로 해결하였으나, 마땅히 이 방법밖에 떠오르지 않아 이렇게 풀었다.
✔️ 정답 코드
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
vector<int> num;
int sum=0;
map<int, int> mode_map;
int median(); // 2번 중앙값
int mode(); // 3번 최빈값
int range(); // 4번 범위
bool compare (pair<int, int> a, pair<int, int> b);
int main(void) {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int N;
cin >> N;
for (int i=0; i<N; i++) {
int temp;
cin >> temp;
sum+= temp;
num.push_back(temp);
auto iter = mode_map.find(temp);
if (iter != mode_map.end())
iter->second++;
else
mode_map.insert(make_pair(temp,1));
}
(round((float)sum/N)==-0) ? cout << "0\n" : cout << round((float)sum/N) << "\n";
sort(num.begin(), num.end());
cout << median() << "\n";
cout << mode() << "\n";
cout << range();
return 0;
}
int median() {
return num[floor(num.size()/2)];
}
int mode() {
vector<pair<int, int>> mode_vector(mode_map.begin(), mode_map.end());
sort(mode_vector.begin(), mode_vector.end(), compare);
int max_value = mode_vector[mode_vector.size()-1].second;
int count=mode_vector.size()-1;
vector<int> result;
while(1) {
if (count == -1)
break;
if (mode_vector[count].second == max_value) // 빈도수 같은 것들만 넣음
result.push_back(mode_vector[count].first);
count--;
}
sort(result.begin(), result.end());
return (result.size() == 1) ? result[0] : result[1];
}
int range() {
return num[num.size()-1] - num[0];
}
bool compare (pair<int, int> a, pair<int, int> b) {
return a.second < b.second;
}
Leave a comment