Algorithm/Java

[백준/JAVA] 4358번 : 생태학

dbfl9911 2024. 10. 22. 16:05
반응형

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

 

[ 문제 요약 ]

미국 전역의 나무 종 분포도를 계산하는 프로그램을 만들어야 합니다. 각 나무 종의 이름을 입력받아 해당 종이 전체에서 차지하는 비율을 소수점 네 번째 자리까지 반올림하여 사전순으로 출력해야 합니다.

 


[ 오답 노트 ]

 기존 오답 코드

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        // TreeMap : 키값이 알파벳순(오름차순)으로 정렬된 상태로 출력
        TreeMap<String, Integer> tm = new TreeMap<>();
        // 입력시 전체 길이 ?
        int sum = 0;
        while(true) {
            sum++;
            int i = 0;
            tm.put(br.readLine(), i);
            if(tm.containsKey(br.readLine())) {
                i++;
            }
        }

        // 비율 구하기? = (전체 합 / 값)
        // 값 변경



        // 값 출력
        for(int i = 0; i < tm.size(); i++) {
            for(Map.Entry<String, Integer> entry: tm.entrySet()) {
                sb.append(entry.getKey() + entry.getValue());
            }
        }
        System.out.println(sb);
    }
}

 

📌 기존 코드의 문제점

1. TreeMap에 값 추가 및 개수 누적 오류

TreeMap에 각 나무 이름을 저장할 때, 단순히 br.readLine()을 사용하여 키를 저장했지만, 각 종의 개수를 제대로 누적하지 못함. 코드 내에서 개수를 늘리는 방식이 제대로 이루어지지 않아, 모든 종의 개수는 1로 유지되었습니다.

 

 

2. 전체 나무 개수 계산 문제

총 나무의 개수를 sum++으로 증가시키는 과정에서 실제 TreeMap에 들어간 데이터와의 연관성을 놓침. TreeMap에 데이터를 추가할 때마다 sum이 증가하지 않으면 total 값을 올바르게 계산할 수 없습니다.

 

 

3. 반복문 오류

while 문 내에서 br.readLine()이 두 번 호출되었기 때문에 두 번째 호출이 이미 이전 입력을 덮어쓰는 문제가 발생했습니다. 즉, 하나의 입력이 아니라 두 줄을 읽는 실수로 인해 TreeMap에 정확히 데이터가 입력되지 않았습니다

 

 

4. 비율 계산 및 출력 형식 누락

원래 코드에서는 나무 종의 비율을 계산하고, 소수점 네 번째 자리까지 출력하는 형식이 구현되지 않았습니다.

 


[ 정답 코드 & 올바른 풀이 ]

 

📌 올바른 풀이

1. TreeMap에 값 추가 및 개수 누적 오류 해결 

getOrDefault() 메서드를 사용하여 이미 저장된 나무 종이라면 기존 개수에 +1을 추가하고, 새로운 종이라면 기본값을 0으로 설정하여 초기화하는 방식으로 수정했습니다.

 

 

2. 전체 나무 개수 계산 문제 해결 

각 줄을 읽을 때마다 sum 변수를 증가시키는 코드로 수정하여 정확한 전체 나무 개수를 계산하도록 변경했습니다.

 

 

3. 반복문 오류 해결 

br.readLine()을 한 번만 호출하여 name변수에 저장하고, 이 값을 이용해 TreeMap에 추가하도록 수정했습니다

 

 

4. 비율 계산 및 출력 형식 누락 해결 

sum을 기준으로 각 나무 종의 비율을 계산한 후, String.format을 이용해 소수점 네 번째 자리까지 포맷하여 출력하도록 수정했습니다.

 

📌 정답 코드

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        // TreeMap : 키값이 알파벳순(오름차순)으로 정렬된 상태로 출력
        TreeMap<String, Integer> tm = new TreeMap<>();
        String name;
        int sum = 0; // 전체 이름 개수

        // 다음에 나올 문자가 null이 아니면
        while((name = br.readLine()) != null) {
            // getOrDefault() 이용 -> 이미 저장된 이름이라면 기존 개수 +1, 새로운 이름이라면 기본값 0
            tm.put(name, tm.getOrDefault(name, 0) + 1);
            sum++;
        }

        // 비율 계산 및 출력 준비
        for(Map.Entry<String, Integer> entry: tm.entrySet()) {
            String s = entry.getKey(); // 이름
            int num = entry.getValue();// 이름 개수
            // 비율 계산 = (한 종의 이름 개수 / 전체 이름 개수) * 100
            double percentage = (num / (double)sum) * 100;
            // String.format을 이용해 소수점 네 번째 자리까지 포맷
            sb.append(String.format("%s %.4f%n", s, percentage));
        }

        System.out.println(sb);
    }
}

 

 

반응형