통계학에서 4가지의 값
1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이
을 구하는 문제다.
첫째줄에 수의 개수 홀수 N이 주어지고, 그 다음 정수들이 N개 주어진다. 입력되는 정수의 절대값은 4000이하다.
차례대로 생각해봐야한다. 음수가 포함되어 있으므로 8001의 공간을 가지는 배열을 만든다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class java_io {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int N = Integer.parseInt(br.readLine());
int[] arr = new int[8001];
//절대값이 4000이므로 4000이 시작점이다.
for(int i=0; i<N; i++) {
arr[Integer.parseInt(br.readLine())+4000]++;
}
//정렬된 index값들을 저장해주기위한 공간
int[] arr_copy = new int[8001];
for(int i=0; i<8001; i++) {
arr_copy[i] = arr[i];
}
int[] arr_index = new int[N];
int num =0;
for(int i=1; i<8001; i++) {
while(arr[i]>0) {
arr_index[num] = i-4000;
arr[i]=0;
num++;
}
}
StringBuilder sb = new StringBuilder();
//1. 산술평균
double avg = 0;
for(int i=0; i<arr_index.length; i++) {
avg +=arr_index[i];
}
sb.append((int)Math.round(avg/(double)N)).append('\n');
//2. 중앙값
sb.append(arr_index[N/2]).append('\n');
//3. 최빈값
int mode =10000;
int mode_max = 0;
boolean flag = false;
for(int i = arr_index[0]+4000; i<=arr_index[N-1]+4000; i++) {
if(arr_copy[i]>0) {
if(mode_max < arr_copy[i]) {
mode_max =arr_copy[i];
mode = i-4000;
flag = true;
}
else if(mode_max == arr_copy[i] && flag ==true) {
mode = i-4000;
flag =false;
}
}
}
sb.append(mode).append('\n');
//4. 범위
sb.append(arr_index[N-1] - arr_index[0]).append('\n');
System.out.print(sb);
}
}
방향을 잡을 때, 풀기 힘든 방향을 잡아서 틀리긴했지만 음수 값을 입력받을 때, 문제가 발생했다. 선 정렬 후에, 값들을 구한게 실패요인이었다. 처음부터 끝까지, 값을 찾아가며 순서를 정해서 푸는 방법을 찾아서 이해하니, 코드를 어떻게 구현할지 구조적인 부분을 먼저 생각해야만 한다는 것을 깨달았다. 아래는 참고한 답안이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class java_io {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int N = Integer.parseInt(br.readLine());
// 입력값의 범위 : -4000 ~ 4000
int[] arr = new int[8001];
/*
* sum = 총 합계
* max = 최댓값
* min = 최솟값
* median = 중앙값
* mode = 최빈값
*/
int sum = 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
// median 과 mode 는 -4000~4000 을 제외한 수로 초기화하면 된다.
int median = 10000;
int mode = 10000;
for(int i = 0; i < N; i++) {
int value = Integer.parseInt(br.readLine());
sum += value;
arr[value + 4000]++;
if(max < value) {
max = value;
}
if(min > value) {
min = value;
}
}
// 순회
int count = 0; // 중앙값 빈도 누적 수
int mode_max = 0; // 최빈값의 최댓값
// 이전의 동일한 최빈값이 1번만 등장했을경우 true, 아닐경우 false
boolean flag = false;
for(int i = min + 4000; i <= max + 4000; i++) {
if(arr[i] > 0) {
/*
* <중앙값 찾기>
* 누적횟수가 전체 전체 길이의 절반에 못 미친다면
*/
if(count < (N + 1) / 2) {
count += arr[i]; // i값의 빈도수를 count 에 누적
median = i - 4000;
}
/*
* <최빈값 찾기>
* 이전 최빈값보다 현재 값의 빈도수가 더 높을 경우
*/
if(mode_max < arr[i]) {
mode_max = arr[i];
mode = i - 4000;
flag = true; // 첫 등장이므로 true 로 변경
}
// 이전 최빈값 최댓값과 동일한 경우면서 한 번만 중복되는 경우
else if(mode_max == arr[i] && flag == true) {
mode = i - 4000;
flag = false;
}
}
}
System.out.println((int)Math.round((double)sum / N)); // 산술평균
System.out.println(median); // 중앙값
System.out.println(mode); // 최빈값
System.out.println(max - min); // 범위
}
}
출처 : Stranger's lab