티스토리 뷰

 


[1] 백준 #4358 생태학

 

4358번: 생태학

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

www.acmicpc.net

 

🔒 문제 설명

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

 

⌨️ 입력

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

 

🖥️ 출력

주어진 각 종의 이름을 사전순으로 출력하고, 그 종이 차지하는 비율을 백분율로 소수점 4째자리까지 반올림해 함께 출력한다.

 


 

 

🗝️Solution

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {

        //[1] 입력을 위한 선언
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        double total = 0;

        //[2] 각 나무들의 종과 나온 횟수를 저장하는 HashMap 선언
        HashMap<String, Integer> trees = new HashMap<>();

        //[3] 나무들 입력 받기
        String input;
        while ((input = br.readLine()) != null) { //나무 해쉬맵 갱신하기
            total ++ ;
            if(trees.containsKey(input)){ // 이미 존재하는 나무라면 count + 1
                trees.put(input, trees.get(input)+1);
            }
            else trees.put(input,1);
        }

        //[4] 사전순 정렬 SortedMap 
        Map<String, Integer> sortedMap = new TreeMap<>(trees);

	//[5] 출력
        double finalTotal = total;
        sortedMap.forEach((tree, count) ->
                System.out.println(tree+" "+String.format("%.4f",(double)count * 100 / (double)finalTotal))
        );
    }
}

 

 

 

[2]  BufferedReader  VS  Scanner(System.in)

- BufferedReader의 장단점

장점 단점
속도가 훨씬 빠르다.
입력된 데이터가 바로 전달되지 않고 버퍼에 채워서 한번에 전달되므로 데이터 처리 효율성이 높다.
많은 양의 데이터를 처리할 때 유리하다.
ENTER만 경계로 인식하고 받은 데이터가 String으로 고정되기 때문에 입력값을 가공하는 작업이 필요하다.

 

 

- BufferReader 기본 사용 방법

BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
int i = Integer.parseInt(br.readLine());

여기서 주의할 점은 BufferedReader로 읽은 데이터 값은  'String'타입으로 고정되므로 다른 타입을 받고 싶다면 꼭 형변환을 해줘야 한다는 것이다.(코드 맨 아랫줄)

 

 

-  BufferedReader로 입력 받은 문장을 분리하고 싶을 때 : StringTokenizer

//1. 띄어쓰기 기준으로 문자열을 분리
StringTokenizer st = new StringTokenizer(문자열); 

//2. 구분자를 기준으로 문자열을 분리
StringTokenizer st = new StringTokenizer(문자열, 구분자); 

/* 3. 구분자를 기준으로 문자열을 분리할 때 구분자도 토큰으로 넣는다. (true) 
* 구분자를 분리된 문자열 토큰에 포함 시키지 않는다. (false) 
* (디폴트 : false) 
*/ 
StringTokenizer st = new StringTokenizer(문자열 , 구분자 , true/false);

 

 

➕더 읽어보기

 

[Java] StringTokenizer 문자열 분리하기 (split과 차이는 뭘까?)

StringTokenizer 클래스란? StringTokenizer 클래스는 문자열을 구분자를 이용하여 분리할 때 사용할 수 있습니다. 만일 BufferedReader 클래스의 메서드로 입력을 읽어들인다면 라인 단위로 읽어들일 수 밖

dev-coco.tistory.com

 

 

- 입력의 끝을 모를 때 : EOF(End Of File) 처리

입력의 개수가 정해지지 않고, 가변적인 상황에서는 보통 while문이나 for문을 사용해서 EOF 조건을 넣어준다. Buffered Reader나 Scanner를 사용할 때 조건문의 구성은 아래와 같이 하면 된다.

 

(1) BufferedReader

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input;
while ((input = br.readLine()) != null) { 
	// input에 입력받은 한 줄이 들어가 있음
}

 

(2)Scanner(System.in)

Scanner scan = new Scanner(System.in);
		
while(scan.hasNext()) {
  //scan에 입력받은 값이 들어가 있음
}

 

 

➕더 읽어보기

 

[Java] 빠른 입출력을 위한 BufferedReader, BufferedWriter, StringTokenizer, StringBuilder

BufferedReader / BufferedWriter BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다. 버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.

rlakuku-program.tistory.com

 


[2] HashMap 

이 문제에서 나무 이름과 입력 횟수를 각각 어디에 저장하고 어떻게 연결할 것인지 정말 고민이 많았다.

각각 Arraylist에 담아서 서로의 인덱스를 저장하는 방법, LinkedList를 사용하는 방법, 클래스를 만들어 객체 단위로 처리하는 방법 등 정말 고민이 많았는데 결국 찾아낸 것은 HashMap 이다. C++ 문제 풀이 때 써봤던 HashMap KeyValue가 짝지어져서 저장되는 자료구조이다.

Key는 하나의 HashMap에서 유일한 것이므로 결국 Key는 '나무 이름', Value는 '나무 입력 횟수'를 저장하면 되는 것이다. 

 

        //[1] HashMap 선언
        HashMap<String, Integer> trees = new HashMap<>();

        //[2] 나무들 입력 받기
        String input;
        while ((input = br.readLine()) != null) { //나무 해쉬맵 갱신하기
            total ++ ;
            if(trees.containsKey(input)){ // 이미 존재하는 나무라면 count + 1
                trees.put(input, trees.get(input)+1);
            }
            else trees.put(input,1);
        }

        //[3] 사전순 정렬 : SrotedMap
        Map<String, Integer> sortedMap = new TreeMap<>(trees);

 

이 때, HashMap은 개체들을 무작위로 저장하는데 우리는 출력할 때 사전 순으로 출력해야한다. 

다양한 방법을 사용할 수 있겠지만 나는 TreeMap을 사용해서 사전순으로 나열했다. 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함