적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

Algorithm/Baekjoon

[Swift 알고리즘] 백준 2108 통계학

hongssup_ 2024. 7. 21. 00:20
반응형

수학, 정렬 - Silver 3 (40분)

 

백준 2108 통계학

문제
1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값
4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이
N개의 수가 주어졌을 때, 네 가지 기본 통계값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.
출력
첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.
둘째 줄에는 중앙값을 출력한다.
셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.
넷째 줄에는 범위를 출력한다.

 

나머지는 간단하게 그냥 구현만 하면 되는데, 최빈값이 약간 함정이다.

1. 변수 선언 - N개의 수를 받아오는 배열 arr, 수들의 합을 구하는 sum, 최빈값을 구하기 위한 dict 를 만들어준다.

2. 산술평균, 중앙값, 범위는 그냥 구하면 되고

3. 가장 많이 나왔던 수를 출력하되, 여러 개 있을 때에는 그 중 두 번째로 작은 값을 출력한다.. 

3-1. 일단 처음 수 저장할 때 해당 수와 나온 횟수를 함께 딕셔너리에 저장해두고

3-2. 정렬.. 을 어떻게 할지가 관건이다.

 

우선 내가 처음 구현했던 코드는 다음과 같이

딕셔너리의 value 가 큰 순서대로 정렬하되, value 가 같을 경우 key 가 작은 순서대로 정렬하도록 해주었다.

이렇게 하면 최빈값이 하나일 경우 가장 첫번째 key 를 출력, 여러개면 두 번째 key 를 출력해주는 방식이다.

let common = dict.sorted(by: { $0.1 == $1.1 ? $0.0 < $1.0 : $0.1 > $1.1 })
print(common[0].value == common[1].value ? common[1].key : common[0].key)

뭐 답은 나오지만 정렬 구현할 때 많이 헷갈리기도 했고, 그다지 좋은 방법은 아닌 듯 하다.

 

다음과 같이 딕셔너리 value 중 최대값을 먼저 구해준 후, 최대값을 value 로 가지는 key 값들을 filter로 거른 다음 정렬을 해주면

훨씬 깔끔하고 간단하게 최빈값을 구할 수 있습네다 👍🏻

let maxValue = dict.values.max()
var temp = dict.filter({ $0.value == maxValue }).keys.sorted()
print(temp.count > 1 ? temp[1] : temp[0])

 

 

 

내 답안 - 89560KB 324ms

import Foundation

let n = Int(readLine()!)!
var arr = Array(repeating: 0, count: n)
var sum = 0
var dict = [Int: Int]()

for i in 0..<n {
    arr[i] = Int(readLine()!)!
    sum += arr[i]
    if dict[arr[i]] != nil {
        dict[arr[i]]! += 1
    } else {
        dict[arr[i]] = 1
    }
}

if n == 1 {
    for _ in 0..<3 {
        print(sum)
    }
    print(0)
} else {
    let sortedArr = arr.sorted()
    let common = dict.sorted(by: { $0.1 == $1.1 ? $0.0 < $1.0 : $0.1 > $1.1 })
    
    print(Int(round(Double(sum) / Double(n))))
    print(sortedArr[n/2])
    print(common[0].value == common[1].value ? common[1].key : common[0].key)
    print(sortedArr[n-1] - sortedArr[0])
}

 

모범 답안 - 86120KB 304ms

import Foundation

let n = Int(readLine()!)!
var array: [Int] = []
var sum = 0
var dict: [Int:Int] = [:]

for _ in 0 ..< n {
    let num = Int(readLine()!)!
    array.append(num)
    sum += num
    dict[num, default: 0] += 1
}

// 산술평균
print(Int(round(Double(sum) / Double(n))))

// 중앙값
array.sort()
print(array[n/2])

// 최빈값
let maxValue = dict.values.max()
var temp = dict.filter({ $0.value == maxValue }).keys.sorted()
print(temp.count > 1 ? temp[1] : temp[0])

// 범위
print(array[n-1] - array[0])
728x90
반응형