[백준 2108] 통계학

백준 2108번 - 통계학

백준 2108번

❓ 문제

수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.


✏️ 풀이

이 문제에서 제일 어려웠고 시간을 많이 썼던 부분은 최빈값을 구하는 부분이었다.

나머지는 수학적 공식으로 쉽게 풀 수 있으니 언급하지 않겠다.

우선, 나는 최빈값에 대해 이렇게 생각하였다.

  1. map<int, int> 형식으로 key 값에 대해 빈도수를 value로 주기로 결정.
  2. 중복되는 수는 map.find(key)로 검색을 하여 존재한다면 value++를 함.
  3. 그리고 이렇게 만들어진 map을 vector<pair<int, int»에 넣음.
  4. pair->second 값으로 sorting
  5. 그 후, 빈도수의 max값과 같은 빈도수를 가진 숫자들을 모두 vector에 넣음.
  6. 위의 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