2108 - 통계학 (Golang)
문제
수를 처리하는 것은 통계학에서 상당히 중요한 일이다.
통계학에서 N개의 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.
- 산술평균 : N개의 수들의 합을 N으로 나눈 값
- 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
- 최빈값 : N개의 수들 중 가장 많이 나타나는 값
- 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다.
그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
예제 입력
5
1
3
8
-2
2
출력
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.
예제 출력
2
2
1
10
분석
언뜻 문제만 보면 쉽게 느껴질 수 있으나, 함정이 많은 문제로 보입니다.
첫번째 산술평균만 해도 자료형이 정확해야하며 ( int 형으로 제출 시 오답 처리 )
세번째 최빈값을 배열로 푼다면 0이 있다는 사실을 기억해야 합니다. ( -4000 ~ 4000 = 8001의 배열 크기 필요 )
풀이
우선 입력값들을 받은 뒤 배열을 복사하여 중앙값 계산을 위한 복사 배열을 만들어 줍니다
또한 나올 수 있는 최대값과 최소값을 산정하여
반복문으로 최대값과 최소값, 모두의 합친 값을 구해주고
전체 합친값을 형변환 해주어 배열의 길이만큼 나눠준 산술평균을 구해줍니다.
위의 복사 배열은 정렬이 되어있으므로 이 것의 /2는 곧 중앙 값이라고 볼 수 있습니다.
최빈값은 따로 함수로 구성을 하였는데
우선 배열의 첫번째 인자를 비교값에 넣어주고
숫자를 세는 변수, 최대 숫자를 세는 변수를 선언해줍니다.
배열의 두번째 인자부터 반복문을 통해 인자가 같으면 counter (숫자를 세는 변수)를 +1해줍니다
또한 이 counter가 maxCounter와 같고 modes(비교값 배열)에 인자가 하나라면 modes에 추가해줍니다
maxCounter 보다 크다면 maxCounter (최대값)이 이 counter로 교체되고 modes도 이 인자하나를 가지는 배열로 초기화 됩니다.
만일 modes (비교값 배열)에 첫번째 인자 외에 다른 인자가 포함되있으면 제일 최빈값이므로 이것을 반환해주고
아니면 첫번째 인자가 최빈값이 됩니다.
소스 코드
package main
import (
"bufio"
"fmt"
"math"
"os"
"sort"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
var length, _ = strconv.Atoi(scanner.Text())
numberArray := make([]int, length)
sortArray := make([]int, length)
for i := 0; i < length; i++ {
scanner.Scan()
numberArray[i], _ = strconv.Atoi(scanner.Text())
}
copy(sortArray, numberArray)
sort.Ints(sortArray)
var sum = 0
var max = -4000
var min = 4000
for i := 0; i < length; i++ {
sum += numberArray[i]
if numberArray[i] > max {
max = numberArray[i]
}
if numberArray[i] < min {
min = numberArray[i]
}
}
fmt.Println(math.Round(float64(sum) / float64(length)))
fmt.Println(sortArray[length/2])
fmt.Println(findMode(sortArray))
fmt.Println(max - min)
}
func findMode(a []int) int {
prevN := a[0]
counter := 0
modes := []int{prevN}
maxCounter := 0
for _, n := range a[1:] {
if prevN != n {
prevN = n
counter = 0
} else {
counter++
}
if counter == maxCounter {
if len(modes) < 2 {
modes = append(modes, n)
}
} else if counter > maxCounter {
maxCounter = counter
modes = []int{n}
}
}
if len(modes) > 1 {
return modes[1]
}
return modes[0]
}
'실습 - Go > 백준' 카테고리의 다른 글
9498 - 시험 성적 (Golang) (0) | 2021.07.29 |
---|---|
1330 - 두 수 비교하기 (Golang) (0) | 2021.07.29 |
2588 - 곱셈 (Golang) (0) | 2021.07.07 |
10430 - 나머지 (Golang) (0) | 2021.07.07 |
10869 - 사칙 연산 (Golang) (0) | 2021.07.07 |
댓글