상냥한 세상 :: [백준]10951번: A+B-4

본문으로 바로가기

[백준]10951번: A+B-4

category Computer Science/BAEKJOON JAVA Practice 2022. 1. 14. 14:00

https://www.acmicpc.net/problem/10951

 

10951번: A+B - 4

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

www.acmicpc.net

  • 문제

 

이전문제랑 다르게 0 0 을 입력해서 반복문을 종료시킨다던가 하는 그런 종료방식이 따로 설정되어 있지 않다. 이를 위해, 우선 별다른 파일 종료 조건 없이, 즉 '입력할 데이터가 더이상 존재하지 않을때' 반복문을 종료하는 방법을 알기위해 EOF(End of File)의 개념부터 집고 넘어가야 한다.  

 

  • EOF의 정의

    End of File의 약자로, 데이터 소스로부터 더이상 읽을 수 있는 데이터가 없음을 나타내는 용어
    -새롭게 라인을 읽어왔는데 그 값이 null이면 더이상 읽을 수 없다는 것을 의미하므로 루프를 종료
    입력의 개수를 모르기때문에 For문보단 While을 이용한다. 

  • Scanner에서의 EOF방식
    Scanner sc = new Scanner(System.in);
    
    while(sc.hasNextLine()) { //입력되는 형식에 따라 달리 작성 
        sc.nextLine(); 
    }
    
    while(sc.hasNextInt()) {
        sc.nextInt();
    }
    정수형일 경우 두개의 메소드 hasNextInt(), hasNext() 중 하나로 써도된다. (hasNext()가 20ms정도 더빨랐다). 

  • BufferedReader에서의 EOF방식
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in);
    String input = "";
    
    while((input = br.readLine()) != null) {
        //......
    }​
  • StirngTokenizer..?
    StringTokenizer은 문자열을 입력하는게아닌, 입력 받은 문자열을 '가공'하는 역할이기에 EOF를 처리한다고 보긴 어렵다. 

  • 코드 1
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        
        while(in.hasNextInt()){
            int A=in.nextInt();
            int B=in.nextInt();
            
            System.out.println(A+B);
        }
        in.close();
    }
}

  • 결과

hasNextInt()사용
hasNext()사용


  • 코드 2
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;

public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb=new StringBuilder();
        StringTokenizer st;
        String str;
        
        while((str=br.readLine())!=null){
            st=new StringTokenizer(str," ");
            int A=Integer.parseInt(st.nextToken());
            int B=Integer.parseInt(st.nextToken());
            sb.append(A+B).append("\n");
        }
        System.out.print(sb);
    }
}

 

이걸 그대로 이클립스에 입력할경우 

1 1
2 2
3 3
4 4
5 5
-----------------------------------------------------

 

여기서 시스템이 계속 입력하라고 요구한다. EOF의 입력방법은 윈도우의 경우 ctrl+Z, 리눅스 계열의 경우 ctrl+D를 눌러주면 sb가 출력된다. 하지만, IDE나 콘솔입력에서 EOF를 주고 싶을땐 어떻게 할 방법이 없어서(엔터입력은 윈도우에선 \r\n, 리눅스에선 \r 이 발생) EOF를상채를 알리는 매크로같은 단축키를 만들어야한다. (통칭 키보드 이벤트)
그 방법중에 하나가 스윙인데.. 문제는 보통 이걸 사용할때 포커스를 하지않으면 안된다. 그러니까 어떤 프로그램을 사용할 때, 거기에 키를 입력하려면 일단 거기로 이동해서 들어가야하는게 포커스인데, 이 문제에선 우리가 따로 프레임을 만들거나 그러지를 않기 때문에.. 포커스도 안만드는셈이다. 그러므로 키보드이벤트를 쓰려는 스윙도 여기선 안되는것으로 판단된다. 
(그냥 이클립스 써서 ctrl+z 누르고 EOF알려주는게 제일 편한 방법인듯..)

 

그리고 String str=br.readLine();을 while밖에서 선언해주냐 안에서 선언해주냐는 의미차이가 있다.

//매 반복마다 str에 br.readLine()을 통해 입력받은 값을 저장하고 null인지 검사
String str;
while((str = br.readLine()) != null) { ... }


//한번만 입력받고 끝내버림
str = br.readLine();
while(str != null) {...}

  • 결과


  • 코드3

 

StringTokenizer가 성능이 좋긴한데, 반복문할때마다 객체를 계속 생성해줘야해서 여기서 시간이 또 뺏길수가 있다. 

while((str=br.readLine())!=null){
    st=new StringTokenizer(str," ");
    //....
}

한자릿수 정수만 입력받는 이 문제에선, 공백의 위치가 고정이다. 다시말해 1 2 를 입력했을때의 공백위치와 10 20을 입력했을때의 공백위치는 다르다.(공백이 10의 0때문에 오른쪽으로 한칸 밀려감) 

 

그래서 그냥 객체생성없이 바로 charAt으로 접근하면 조금이라도 시간을 아낄수가 있다. 

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main{
    public static void main(String[] args)throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb=new StringBuilder();
        
        String str;
        
        while((str=br.readLine())!=null){
            int A=str.charAt(0)-'0';
            int B=str.charAt(2)-'0';
            
            sb.append(A+B).append("\n");
        }
        System.out.print(sb);
    }
}

  • 결과


 

  • 코드 1, 2, 3 성능 비교

Scanner 사용
BufferedReader+StringBuilder+StringTokenizer사용
BufferedReader+StringBuilder+charAt 사용