PS

[백준 - Swift] 4358 생태학

itisjustK 2023. 1. 20. 13:01

문제

https://www.acmicpc.net/problem/4358

 

4358번: 생태학

프로그램은 여러 줄로 이루어져 있으며, 한 줄에 하나의 나무 종 이름이 주어진다. 어떤 종 이름도 30글자를 넘지 않으며, 입력에는 최대 10,000개의 종이 주어지고 최대 1,000,000그루의 나무가 주어

www.acmicpc.net

 

 

풀이

 - 제한 조건 : 입력값 < 10^6, 종류 < 10^4

 

1. 입력값을 담은 배열을 for문으로 순회하면서

2. 딕셔너리 형태의 board에 종의 개수를 추가한다. 이때 딕셔너리에 key 값들을 미리 선언해둔다 (나중에 포함 여부를 분기로 코드를 작성하면 시간복잡도가 늘어나기 때문이다)

3. 딕셔너리를 순회하면서 [String] 타입의 ans에 "종 이름 + 비율"을 추가한다

4. ans를 정렬한다

5. ans값을 하나씩 출력한다

 

 

코드

import Foundation

var data = [String](), board = [String:Int](), ans = [String](), total = 0

while let input = readLine() {
    data.append(input)
}

let species = Set(data)
species.forEach{ board[$0] = 0 }

for entity in data {
    let count = board[entity]! + 1
    board[entity] = count
}

total = board.reduce(0, { $0 + $1.value })

for entity in board {
    ans.append("\(entity.key) \(String(format: "%.4f", (Double(entity.value*100)/Double(total))))")
}

ans.sort()
ans.forEach{ print($0) }

 

 

개선점

1. input 담는 배열 따로 선언 안하고 바로 딕셔너리에 넣기

2. 딕셔너리 타입에 default 프로퍼티 사용해서 초기값 세팅해줄 수 있다. (나는 0으로 한 번 할당, 1씩 더하기 총 2번 돌았음)

3. reduce 쓸 때 reduce(0, +)를 쓰면 그냥 합 도출 가능

 

// 딕셔너리 default
while let input = readLine() {
    board[input, default: 0] += 1
}

// reduce
total = board.values.reduce(0,+)