
내가 생각했을때 문제에서 원하는부분
The input is a list of office supplies with one item per line.
End-of- input is denoted by the string “EOI”.
Print the total cost of all the items in the list.
The output must start with a dollar sign, “$” and the total printed with exactly two decimal digits.
내가 이 문제를 보고 생각해본 부분
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
이 부분은 프로그램이 사용자로부터 입력을 받는 통로를 설정하는 과정이다.
System.in은 키보드와 같은 표준 입력 장치에서 들어오는 '바이트' 형태의 데이터를 의미한다.
InputStreamReader(System.in)는 이 바이트 데이터를 우리가 읽을 수 있는 '문자' 형태로 바꿔주는 역할을 한다.
컴퓨터가 바이트를 문자열로 해석할 수 있도록 돕는다.
new BufferedReader(...)는 이 InputStreamReader를 감싸서, 한 줄씩 통째로 텍스트를 읽을 수 있도록 해주는 도구이다.
이렇게 하면 한 글자씩 읽는 것보다 훨씬 빠르고 효율적으로 많은 양의 입력을 처리할 수 있다.
Map<String, Double> itemCosts = new HashMap<>(); 부터 itemCosts.put("Ink", 66.95); 까지
여기서는 문제에 나와 있는 사무용품들의 이름과 그에 해당하는 가격을 미리 저장해두는 공간을 만드는 과정이다.
Map<String, Double> itemCosts = new HashMap<>();는 itemCosts라는 이름의 '지도' 같은 것을 만드는 것과 같다.
이 지도에는 물품의 '이름(문자열)'을 찾으면 그 물품의 '가격(소수점 있는 숫자)'을 알려주도록 설계되어 있다.
itemCosts.put("Paper", 57.99);와 같이 put 명령을 사용해서, "Paper"라는 이름에는 "57.99"라는 가격이 연결되어 있다고 지도에 하나씩 기록해두는 것이다.
이렇게 미리 정보를 등록해두면, 나중에 "Paper"가 나왔을 때 이 지도에서 즉시 가격을 찾아낼 수 있다.
double totalCost = 0.0;
이 변수는 구매한 모든 사무용품의 총 비용을 저장하기 위한 공간이다.
double은 소수점 아래 숫자를 포함할 수 있는 자료형이고, 0.0으로 초기화해서 아직 아무것도 구매하지 않은 상태인 '0원'으로 시작하도록 한다.
이제부터 여기에 상품 가격들을 하나씩 더해나갈 거다.
String item;
이 변수는 BufferedReader를 통해 키보드에서 한 줄씩 읽어들일 사무용품 이름을 임시로 저장하는 용도로 사용된다.
예를 들어 "Binders"나 "Calendar" 같은 이름이 여기에 들어오게 될거다.
while ((item = br.readLine()) != null && !item.equals("EOI")) { ... }
이 부분이 사용자가 입력하는 사무용품 목록을 처리하는 핵심적인 반복문이다.
(item = br.readLine()) != null: br.readLine()은 키보드에서 한 줄을 읽어 item 변수에 넣어준다.
만약 더 이상 읽을 내용이 없으면(파일의 끝이나 입력이 종료되면) null을 반환하게 되는데, 이때 반복문을 멈추기 위한 조건이다.
!item.equals("EOI"): 읽어들인 item이 "EOI"(End Of Input) 문자열과 같지 않으면 반복을 계속한다.
문제에서 "EOI"가 입력의 끝을 나타낸다고 했으니, 이 문자열이 나타나면 더 이상 계산할 물품이 없다는 뜻이다.
즉, "입력 줄을 계속 읽되, 입력이 끝나거나 'EOI'라는 글자가 나오면 멈춰라!" 라는 의미이다.
totalCost += itemCosts.get(item);
while 루프 안에서 실행되는 이 명령은 현재 읽어들인 item의 가격을 총 비용에 더하는 역할을 한다.
itemCosts.get(item)은 아까 우리가 만든 itemCosts 지도에서 item 변수에 들어있는 상품 이름을 가지고 해당 상품의 가격을 찾아온다.
예를 들어 item이 "Binders"라면 22.50을 가져오겠다.
totalCost += ...는 이렇게 찾아온 가격을 totalCost에 누적해서 더한다는 의미이다.
루프가 반복될 때마다 totalCost는 새로운 상품의 가격으로 계속해서 증가하게 된다.
System.out.printf("$%.2f%n", totalCost);
모든 상품의 비용 계산이 끝나면, 이제 최종 totalCost를 문제에서 요구하는 형식에 맞춰 출력해야 한다.
System.out.printf(...)는 형식을 지정해서 출력할 때 사용되는 명령어이다.
"$%.2f%n"은 출력될 내용의 '설계도'와 같다.
$: 달러 기호는 말 그대로 출력된다.
.2f: f는 '소수점'이 있는 숫자를 의미하고, .2는 소수점 아래 두 자리까지만 표시하라는 명령이다.
만약 세 번째 자리에서 반올림이 필요하면 자동으로 처리해준다.
예를 들어 201.056은 201.06으로, 201.0은 201.00으로 출력된다.
%n: 줄을 바꿔주는 역할을 합니다. 이렇게 totalCost 변수의 값이 "$%.2f"라는 형식에 맞춰 출력된다.
br.close();: BufferedReader를 닫아 시스템 리소스를 해제한다.
코드로 구현
package baekjoon.baekjoon_32;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
// 백준 5342번 문제
public class Main1263 {
public static void main(String[] args) throws IOException {
// BufferedReader를 사용하여 효율적으로 입력을 읽습니다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 사무용품 이름과 그에 해당하는 가격을 저장할 Map을 선언합니다.
// Map<String, Double>을 사용하여 문자열(상품 이름)을 키로, double(가격)을 값으로 저장합니다.
Map<String, Double> itemCosts = new HashMap<>();
itemCosts.put("Paper", 57.99);
itemCosts.put("Printer", 120.50);
itemCosts.put("Planners", 31.25);
itemCosts.put("Binders", 22.50);
itemCosts.put("Calendar", 10.95);
itemCosts.put("Notebooks", 11.20);
itemCosts.put("Ink", 66.95);
// 총 비용을 저장할 변수를 선언하고 0.0으로 초기화합니다.
double totalCost = 0.0;
String item; // 각 줄에서 읽어들일 상품 이름을 저장할 변수
// 입력을 한 줄씩 읽어오면서 "EOI" 문자열이 나올 때까지 반복합니다.
// br.readLine()이 null이 아닌지 확인하여 입력 스트림의 끝(EOF)도 처리합니다.
while ((item = br.readLine()) != null && !item.equals("EOI")) {
// Map에서 현재 읽어온 상품(item)의 가격을 가져와 totalCost에 더합니다.
// itemCosts.get(item)은 해당 키에 대한 값을 반환합니다.
// 만약 키가 존재하지 않으면 null을 반환하지만, 문제 조건상 항상 유효한 상품 이름이 들어온다고 가정할 수 있습니다.
// 더 안전하게는 getOrDefault(item, 0.0)을 사용할 수도 있습니다.
totalCost += itemCosts.get(item);
}
// 모든 상품의 비용 계산이 완료된 후, 결과를 출력합니다.
// System.out.printf를 사용하여 출력 형식을 지정합니다.
// "$%.2f%n":
// - "$": 달러 기호를 그대로 출력합니다.
// - ".2f": double 값을 소수점 이하 두 자리까지 출력합니다. (세 자리 이상은 반올림, 한 자리 이하는 0으로 채움)
// - "%n": 플랫폼에 독립적인 줄바꿈 문자를 출력합니다. (System.out.println의 줄바꿈과 동일)
System.out.printf("$%.2f%n", totalCost);
// 사용한 BufferedReader를 닫아 자원을 해제합니다.
br.close();
}
}
코드와 설명이 부족할수 있습니다. 코드를 보시고 문제가 있거나 코드 개선이 필요한 부분이 있다면 댓글로 말해주시면 감사한 마음으로 참고해 코드를 수정 하겠습니다.