관리 메뉴

이 세계에선 내가 개발자?

[4358/Swift] 생태학 본문

알록리즘/BAEKLOG

[4358/Swift] 생태학

민디고 2023. 6. 2. 15:35

*** 언어는 Swift! ***

 

한동안 블로그를 올리다가 안올렸던 나는 이대로는 안되겠다 싶어서 다시 티스토리를 켰다.

(사실 문제를 풀지 못해서 못 올린 것도 있지만)

 

벌써 7회차에 접어든 알고리즘 스터디(a.k.a 낮평이알 스터디) 

앞으로 점점 더 어려워질 것 같은데 내가 따라갈 수 있을지가 정말 걱정이다. 그래도 어디 한번 가보자고!

 

이번 문제는 4358번 생태학이라는 문제이다.

자세한 문제는 아래와 같다. (더 자세한 문제는 이미지를 클릭하면 볼 수 있다.)

 

결론적인 부분은 각 종이 전체에서 몇 %를 차지하는지 구하는 프로그램인데 솔직히 처음에는 이해가 가지 않았다.

전체에서 몇 %인데 그 전체가 어느 전체인지, 뭔가 따로 주는 데이터가 (API 같은) 있는건지 이미 결론적으로 나와있는 종의 %가 있는건지 뭔지 몰랐다.

그래서 다시 문제를 잘 살펴보니 예제 입력 부분에 같은 종의 이름이 여러개 있다는 것을 알게 되었다.

그제서야 나는 예제 입력 받은 종들 기준으로 해당 종이 몇 펴센트 차지하고 있는지 구하는 것이구나! 라는 걸 깨닫게 되었다.

 

자 그럼 오늘도 어김없이 문제를 쪼개보자

 

1. 한 줄에 하나의 나무 종 이름이 주어진다.

2. 백분율을 구하고, 소수점 네번째 자리까지 반올림한다.

3. 사전 순으로 출력한다.

 

이렇게 나눠볼 수 있었다. 이제 본격적으로 시작해보자 ദ്ദി ᵔ∇ᵔ )

 

1. 한 줄에 하나의 나무 종 이름이 주어진다.

나무의 종은 Dictionary를 이용해 입력받는다. 갯수를 수월하게 저장하기 위해서이다.

나무 전체의 갯수를 저장하기 위해 allCount도 만들어준다.

var treeArray: [String: Double] = [:]
var allCount: Double = 0

 

여기서 조금 집중해야했던 게 나무 종의 갯수가 정해져있지 않다는 것이었다. 그러니 마지막 공백이 나올 때까지 입력받아야했다.

while 문을 이용해 공백이 나올 때 까지 입력을 받는다.

// 한 줄에 하나의 나무 종 이름이 주어진다.
while true {
    // 추가로 입력받은게 비어있을 경우 break
    if let tree = readLine(),
       !tree.isEmpty
    {
        allCount += 1
        treeArray[tree] = (treeArray[tree] ?? 0) + 1
    } else {
        break
    }
}

만약 추가로 입력 받은 tree가 공백이라면 break, 아니라면 allCount를 하나씩 더해주고 treeArray에 해당 tree key를 가진 value를 하나씩 더해준다.

만약 Ash 라는 나무의 종이 들어온다면

treeArray에서 Ash 라는 키를 가진 값을 찾고 그 값에 1을 더해준다. 이렇게 하면 모든 나무를 입력받았을 때 동일한 나무에 대해서는 value가 2, 3 이렇게 더해져있는 것을 볼 수 있다.

 

2. 백분율을 구하고, 소수점 네번째 자리까지 반올림한다.

이제 백분율을 구해보자, persentage라는 변수를 선언해준 뒤 for 문을 이용해 Dictionary 안의 값들을 꺼내와서 계산을 해준다.

var persentage: Double = 0.0

// 백분율 구하기
for (key, value) in treeArray {
    persentage = (value / allCount) * 100

    // 소수점 네번째 자리까지 반올림
    treeArray[key] = round(persentage * 10000) / 10000
}

소수점 네번째 자리까지 반올림을 하기 위해 반올림 함수인 round을 사용해주고 구해놓은 백분율에 10000을 곱해주고 나눠준다.

그럼 3.4482758620689653 이렇게 나오는 값이 반올림해서 3.4483 이렇게 나오게 된다.

 

3. 사전 순으로 출력한다.

자 이제 마지막으로 사전순으로 출력해보자. Dictionary 에도 sorted가 있다. sorted의 기준이 key 이기 때문에 키를 비교하여 오름차순으로 정렬해준다.

그리고 출력해준다.

// 사전 순으로 출력
let sortedTree = treeArray.sorted { $0.0 < $1.0 }
for i in 0..<sortedTree.count {
    print("\(sortedTree[i].key) \(String(format: "%.4f", sortedTree[i].value))")
}

여기서 마지막에 String(format: "%.4f", value) 를 사용한 이유는 소수점 네번째 자리까지 표현하기 위해서이다.

위에서 소수점 네번째 자리까지 구했는데 어째서 출력할 때 이 행동을 또 하냐면 만약 value가 50으로 딱 떨어질 때는 아무리 반올림 계산을 해도 50.0 으로밖에 나오지 않는다.

하지만 이 문제의 핵심 조건은 소수점 네번째 자리까지 출력해야한다는 점이다.

그러니 50도 50.0000 으로 출력해줘야한다.

그러므로 문자열의 포맷을 소수점 네자리까지 출력하도록 변경해준다.

 

이렇게하면 사전 순으로 백분율을 구한 정답이 나오게 된다.

오늘도 한 건 해결 \ \ \\٩(。•ω•。)و // / /

'알록리즘 > BAEKLOG' 카테고리의 다른 글

[9095/Swift] 1, 2, 3 더하기  (2) 2023.06.15
[14495/Swift] 피보나치 비스무리한 수열  (0) 2023.06.14
[14582/Swift] 오늘도 졌다  (0) 2023.05.12
[2607/Swift] 비슷한 단어  (0) 2023.05.11
[2164/Swift] 카드2  (0) 2023.05.10