BAEKJOON_study

[백준_JAVA] 25304 영수증 풀이

universe8 2023. 9. 14. 21:00

나는 [문제] > [단계별로 풀어보기] 순으로 문제를 풀고 있는데,

 

 

25304번 영수증 문제부터는 Scanner를 이용해서 문제를 풀면 '컴파일에러'가 뜬다.

시간제한이 초과한것 같다..

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 영수증에 적힌 총 금액 X를 입력 받습니다.
        int X = scanner.nextInt();

        // 영수증에 적힌 물건의 종류의 수 N을 입력 받습니다.
        int N = scanner.nextInt();

        int calculatedTotal = 0; // 물건의 가격과 개수로 계산한 총 금액을 저장할 변수

        // N개의 물건 정보를 입력 받고 계산합니다.
        for (int i = 0; i < N; i++) {
            int a = scanner.nextInt(); // 물건의 가격
            int b = scanner.nextInt(); // 물건의 개수
            calculatedTotal += (a * b); // 가격과 개수를 곱해서 총 금액에 더합니다.
        }

        // 계산한 총 금액과 영수증에 적힌 총 금액을 비교하여 출력합니다.
        if (calculatedTotal == X) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }

        // 스캐너를 닫습니다.
        scanner.close();
    }
}

 

이젠 Scanner대신 BufferedReader를 이용해서 문제를 풀어야 한다!

#1. 첫번째 방법

//필요한 패키지와 클래스 import 하는 부분
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
    
   		//BufferedReader를 사용하여 입력을 처리할 준비를 합니다.
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // 영수증에 적힌 총 금액 X를 입력 받습니다.
        int X = Integer.parseInt(br.readLine());

        // 영수증에 적힌 물건의 종류의 수 N을 입력 받습니다.
        int N = Integer.parseInt(br.readLine());

        int calculatedTotal = 0; // 물건의 가격과 개수로 계산한 총 금액을 저장할 변수

        // N개의 물건 정보를 입력 받고 계산합니다.
        for (int i = 0; i < N; i++) {
        
        //StringTokenizer를 사용하여 현재 줄을 공백으로 분할하고 각 물건의 가격과 개수를 가져옵니다.
            StringTokenizer st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken()); // 물건의 가격
            int b = Integer.parseInt(st.nextToken()); // 물건의 개수
            
            calculatedTotal += (a * b); // 가격과 개수를 곱해서 총 금액에 더합니다.
        }

        // 계산한 총 금액과 영수증에 적힌 총 금액을 비교하여 출력합니다.
        if (calculatedTotal == X) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }

        // BufferedReader를 닫습니다.
        br.close();
    }
}

N개의 물건 정보를 입력 받고 계산하는 부분에서 여러가지 방법을 사용할 수 있는데,

가장 간단하게 for 루프를 사용하여 N번 반복하는 방법을 사용했다.

 

 

참고로 아래 두 줄은 같은뜻이다 위의 코딩을 아래처럼 줄여서 쓸 수 있다.

calculatedTotal = calculatedTotal + (a * b);

calculatedTotal += (a * b);

 

그리고 IF조건문도 아래와 같이 줄여서 쓰는 방법이 있다.

//IF조건문 방법1
if (calculatedTotal == X) {
    System.out.println("Yes");
} else {
    System.out.println("No");
}

//IF조건문 방법2
System.out.println( ( X == Sum )?"Yes":"No" );

 

#2. 두번째 방법

두번째 방법은 for 반복문 안에서 tokens라는 배열을 선언하고, Steing의 split 매서드를 사용하여 입력받은 값을 처리하는 방법이다. 이 방법을 사용하면 import부분에 [import java.util.StringTokenizer;] 을 사용하지 않을 수 있다.

 // N개의 물건 정보를 입력 받고 계산합니다.
        for (int i = 0; i < N; i++) {
            String[] tokens = br.readLine().split(" ");
            int a = Integer.parseInt(tokens[0]); // 물건의 가격
            int b = Integer.parseInt(tokens[1]); // 물건의 개수
            calculatedTotal += (a * b); // 가격과 개수를 곱해서 총 금액에 더합니다.
        }

 

#3. 세번째 방법

Java Stream을 활용하여 문제를 해결하는 방법이다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Collectors;

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

        // 영수증에 적힌 총 금액 X를 입력 받습니다.
        int X = Integer.parseInt(br.readLine());

        // 영수증에 적힌 물건의 종류의 수 N을 입력 받습니다.
        int N = Integer.parseInt(br.readLine());

        // N개의 물건 정보를 입력 받고 계산합니다.
        List<String> lines = br.lines().limit(N).collect(Collectors.toList());
        int calculatedTotal = lines.stream()
                .map(line -> line.split(" "))
                .mapToInt(tokens -> Integer.parseInt(tokens[0]) * Integer.parseInt(tokens[1]))
                .sum();

        // 계산한 총 금액과 영수증에 적힌 총 금액을 비교하여 출력합니다.
        if (calculatedTotal == X) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }

        br.close();
    }
}

력받은 값으로 물건의 총 가격을 계산하는 방법으로 Java Stream 사용했다.

br.lines()를 사용하여 입력 스트림에서 각 줄을 읽어와 List로 수집한 다음,

Stream을 활용하여 각 물건의 가격과 개수를 곱하여 총 가격을 계산하여 결과를 출력한다.

 

스트림을 사용하 간결하게 코드를 작성할 수 있다.

#. Java Stream

자바 스트림에 대해서 좀 더 자세히 설명 해보면,

Java Stream Java 8부터 추가된 기능으로, 데이터를 처리하고 조작하는데 사용된다.  Stream은 데이터를 다루는데 함수형 프로그래밍의 개념을 도입하여 코드를 간결하게 작성할 수 있도록 도와.

 

위에 java stream을 사용해서 코드작성한 부분을 조금 더 자세하게 풀이해보면,

List<String> lines = br.lines().limit(N).collect(Collectors.toList());
int calculatedTotal = lines.stream()
        .map(line -> line.split(" "))
        .mapToInt(tokens -> Integer.parseInt(tokens[0]) * Integer.parseInt(tokens[1]))
        .sum();
  1. br.lines() 메서드는 BufferedReader에서 한 줄씩 읽어오는 Stream을 생성. 각 줄은 문자열로 표현.
  2. .limit(N)은 스트림에서 최대 N개의 요소만 유지하도록 하는 기능을 해서. 여기서는 입력으로 주어진 물건의 종류의 수 N만큼의 줄만 읽어.
  3. .collect(Collectors.toList())는 스트림의 요소를 List로 수집한다. 이렇게 생성된 lines 리스트는 각 줄의 문자열을 요소로 가지고 있다.
  4. lines.stream()lines 리스트를 스트림으로 변환.
  5. .map(line -> line.split(" "))은 각 줄을 공백 문자로 분할하여 문자열 배열로 변환한다. 각 배열에는 물건의 가격과 개수가 포함.
  6. .mapToInt(tokens -> Integer.parseInt(tokens[0]) * Integer.parseInt(tokens[1]))은 문자열 배열을 정수로 변환하고, 물건의 가격과 개수를 곱하여 총 가격을 계산.
  7. .sum()은 모든 정수 값을 합산하여 최종 총 가격을 계산.

이렇게 Java Stream을 사용하면 데이터 처리 과정을 간결하게 표현할 수 있고, 함수형 스타일로 데이터를 조작할 수 있다. Stream은 병렬 처리와 필터링 같은 다양한 연산도 제공하므로, 다양한 데이터 처리 작업에 유용하게 활용할 수 .

 

 

-끝-

반응형