코딩테스트/BOJ

[BOJ] 4358 생태학 - JAVA

5월._. 2023. 6. 6.
728x90

1. 문제

 

4358번: 생태학

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

www.acmicpc.net

생태학에서 나무의 분포도를 측정하는 것은 중요하다. 그러므로 당신은 미국 전역의 나무들이 주어졌을 때, 각 종이 전체에서 몇 %를 차지하는지 구하는 프로그램을 만들어야 한다.


2. 풀이

1.  문제에서 몇 그루의 나무를 입력으로 주는 지 알려주지 않는다. 따라서 입력받은 값이 null인지 체크하는 반복문이 필요하다.

2.  map에 key가 있다면 value에 +1한 값, 없다면 1을 저장한다.

3.  총 나무 그루 개수도 count에 저장한다.

4.  Entry타입을 저장하는 ArrayList를 만들어서 map의 entryset을 저장한다. 

5.  key기준으로 오름차순 정렬한다.

6.  StringBuilder를 사용해서 key와 value*100/count를 더한다. 이때, round를 사용하면 안된다. round를 사용하면 소수점 네 자리를 맞출 수 없다. 예를 들어 50이 답일 경우, 50.0000으로 나와야 하는데 round를 사용하면 50만 나온다. 따라서 String.format을 사용한다.

7.  sb를 출력한다.

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

public class BOJ_4358_생태학 {
   public static void main(String[] args) throws IOException {
//      System.setIn(new FileInputStream("input.txt"));
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

      Map<String, Integer> map = new HashMap<>();
      String str;
      double count = 0;
      while((str = in.readLine()) != null){
         map.put(str, map.getOrDefault(str,0)+1);
         count++;
      }

      ArrayList<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
      Collections.sort(list,(a,b)->a.getKey().compareTo(b.getKey()));

      StringBuilder sb = new StringBuilder();
      for(Map.Entry<String, Integer> entry:list){
         sb.append(entry.getKey()).append(" ").append(String.format("%.4f",100*entry.getValue()/count)).append('\n');
      }

      System.out.print(sb);
   }
}

3. 결과

처음에 TreeMap으로 써서 따로 list를 사용하지 않았다. 

두번째는 HashMap을 사용한 후 list를 만들어서 새로 정렬했다. 그 결과 메모리는 더 늘어나고(list크기) 시간은 줄어들었다.(TreeMap은 입력받을 때마다 내부적으로 정렬됨)

댓글