문제 이름 : A + B - 5


문제

두 정수 AB 를 입력받은 다음, A + B 를 출력하는 프로그램을 작성하시오.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다.

각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 AB 가 주어진다.

(0 < A, B < 10)

입력의 마지막에는 0 두 개가 들어온다 : 0 0


예제 입력 1

1 1
2 3
3 4
9 8
5 2
0 0

예제 출력 1

2
5
7
17
7

이 문제는 입력된 문자열을 비교하는 데 집중하는 문제이다.

이전에 Standard Input 을 설명하면서, 프로그램의 입력 소스를 프로그램이 어떻게 활용하는지 설명 한 적이 있다.

결국 입력값은 문자 이다. 문자가 숫자이던, 특수문자이던, 문자이던, 모두 동일하다.

이를 나중에 특정한 숫자 유형이나 바이트 로 변환하는 과정 등이 있을 뿐이다.


따라서, 이 글을 보는 독자들이 선호하는 입력 클래스에서,

문자열을 정확하게 비교하는 클래스 혹은 메서드 와, EOF 를 발견하는 메서드를 검색하여 사용하면 된다는 것이다.

EOF : End Of File


이 문제는 Java 로 풀이하므로, 주로 Scanner 이나 BufferedReader 입력 클래스를 사용 할 것이다.

이 풀이를 보는 사람들은 아마 초보자일 가능성을 염두하므로, 이전까지 Scanner.nextInt() 메서드를 사용하거나,

Integer.parseInt(st.nextToken()) 을 사용하는 습관까지 고려하여 풀이를 2 개로 분리하겠다.

  1. 마지막 숫자가 둘 다 0, 0 으로 나올 경우, 무한루프를 종료
  2. 마지막 줄의 내용이 0 0 일 경우, 무한루프를 종료

필자는 Scanner 를 사용하지는 않는다. BufferedReader 클래스를 사용하여 입력을 받으므로,

Scanner 클래스의 .nextInt() 메서드를 사용하길 바란다.

참고 :

Scanner.nextInt()BufferedReader 로 줄을 읽고, StringTokenizer 클래스로 토큰 하나를 읽은 후,

이를 Integer.parseInt(token) 하는 것을 축약하는 것과 비슷하다.

Scanner 클래스는 입력을 위해 다양하고 간단한 메서드 유틸리티를 제공하지만,

그만큼 세밀하게 상황을 분리하여 입력을 받기 애매 할 수 있으므로,

필자는 BufferedReaderStringTokenizer 를 사용하여 이를 분리하여 상황에 맞게 사용한다.


Answer 1 - 마지막 줄을 숫자로 인식하여 종료

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

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

        // 무한히 반복한다.
        while(true) {
            // 하나의 줄을 읽고, 토큰으로 분리할 유틸리티 클래스 선언 
            StringTokenizer st = new StringTokenizer(br.readLine());

            int A = Integer.parseInt(st.nextToken());
            int B = Integer.parseInt(st.nextToken());

            // 루프 탈출 조건
            if(A == 0 && B == 0)
                break;

            // 출력 
            System.out.println(A + B);
        }
    }
}

반복문(while) 의 종료가 곧 프로그램의 종료를 의미한다.

따라서, 이에 대한 종료 조건을 숫자로 각각 곧바로 파싱하여 계산한다.

A, B 둘 다 0 이여야 반복문을 탈출하며, 곧바로 프로그램이 종료된다.


Answer 2 - 문자열로 비교하여 종료

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

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

        // 입력 문자열을 저장할 str 초기화, 빈 문자열은 null 이 아님.
        String str = "";

        // str에 문자열을 저장하는데, 이 문자열이 "0 0" 과 동일하면 탈출한다.
        while(!(str = br.readLine()).equals("0 0")) {

            // 위의 조건비교식을 계산하며 str에 새로운 문자열이 들어왔으므로, 새로운 내용의 토큰으로 파싱이 가능하다.
            StringTokenizer st = new StringTokenizer(str);

            int A = Integer.parseInt(st.nextToken());
            int B = Integer.parseInt(st.nextToken());

            System.out.println(A + B);
        }
    }
}

가독성을 증가시키기 위해서 while(true) 이후,

반복문 내용에서 따로 내부의 내용을 break 조건으로 만들 수 있었지만,

이러한 형식으로 코드를 단축시킬 수 있다는 것을 보여주고 싶었다.

while() 괄호 내의 비교식 계산 과정 중에,

이에 대한 내용을 계산하기 위해 입력 과정이 일어나며, 직후 true, or false 결과값이 나오는 것이다.


그리고 이 코드에서 가장 중요한 것은,

str == "0 0" 이 아니라, str.equals("0 0") 으로 작성되었다는 것이다.


String 이 단어는 Primitive 타입이 아니다.

그러니까, 이 String 이란 단어는 클래스 를 의미하며,

== 연산자를 사용하면, 클래스의 주소가 동일한가를 본다는 것이다.

당연하게도 기존의 String str 클래스의 주소와 계속해서 생성되는 "0 0" 의 주소가 같을리가 없다.

따라서, 내부의 값을 직접 비교해주는 String.equals() 메서드를 사용하는 것이다.


Conclusion

여기까지 보았다면 아마 같은 내용의 다른 문제도 풀게 될 것인데,

여기서는 EOF 를 인식하는 문제이다.

마지막 입력은 어떠한 문자열도 아니며, 그저 EOF 이다.

이러한 경우, String.equals() 메서드가 아니라, == 연산자를 사용하여 null 과 비교하면 된다.

(str = br.readLine()) == null 이 코드는,

입력 소스가 EOF 즉, 내용이 없다는 표식을 인식했느냐를 말하는 것이다.


Scanner 입력 클래스를 이용한 방식은 아마 문자열을 인식하는 메서드를 이용 할 것이다.

이는 다른 곳에서 찾아보길 바란다.

'백준-단계별로 풀어보기 > 3-반복문' 카테고리의 다른 글

백준 2439 - 별 찍기 2  (0) 2024.08.06
백준 2739 - 구구단  (1) 2024.07.31