ejyoo's 개발 노트

1000번 : A+B 본문

문제풀이/백준 입출력과 사칙연산

1000번 : A+B

ejyoovV 2021. 3. 3. 10:42

👉🏻 문제분석 : 입력 받을 때 공백단위로 주어짐

👉🏻 문제 풀이 방법 : 2가지 방법

출력에서 System 클래스(System.out.println()), BufferedReader, StringBuilder, StringBuffer을 이용해왔는데

입력에도 여러가지 방법이 있음.

👉🏻 방법1)

import java.util.Scanner;

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

가장 기초적인 입력방법.

  • in.nextInt : 숫자로 입력
  • in.next() : 문자열 입력 시 공백 전 까지만 받음
  • in.nextLine() : 문자열 입력 시 Enter 입력 전까지만 받음

next()의 경우 에러가 발생할 수 잇는 경우가 많아 문자열 입력 형태는 nextLine()을 많이 씀.

👉🏻 BufferedReader

BufferedReader 쓰는 방식이며 BufferedWriter와 객체 생성 방법이 매우 유사하다.

BufferedReader의 경우 문자열을 받는 대표적인 방법은 readLine()과 read() 이다.

이 둘의 차이는 readLine()은 한 행을 읽어오고 read()는 한 문자만 읽어온다.

특별한 경우가 없는 한 readLine()을 쓴다.

  • read() 주의점 1) : 한문자만 읽어옴

    read()의 경우 키보드로 입력한 문자 한 개를 아스키코드(문자)로 읽어 정수형태로 반환된다.

    즉 0을 입력하더라도 문자로 인식하여 실제 변수에는 아스키코드 값인 48이 저장된다.

    아래 자바 API에서 설명이 나와있다.

    물론 해당 값을 출력하면 아스키 값으로 출력된다.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	public static void main(String[] args) throws IOException{
     
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    		int a = br.read(); //5를 입력한다.
    		
    		System.out.print(a); //아스키 코드 값인 53이 출력
    		
    		//만약 53을 입력할 경우 문자 한 개만 읽기 때문에 결국 5만 읽어서 53이 출력됨.
    	}
    }

    53을 입력하는 경우 하나만 읽기 때문에 5의 아스키 코드 값인 53이 출력된다.

    이 문제를 해결하려면 아래와 같이 수정해야 한다.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	public static void main(String[] args) throws IOException{
     
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    //		방법 1 : 입력한 값에 0을 빼준다.
    		int a = br.read() - '0';
    		System.out.println(a);//입력한 값 그대로 출력됨.
    		
    //		방법 2 : '0'은 아스키 코드 값으로 48임. 48을 뺀다.
    		int b = br.read()-48;
    		System.out.println(b);
    	}
    }

    그래서 만약 문자를 받을 때 입력한 값 그래도 정수로 쓰고 싶다면 '0'의 아스키 코드 값인 48 또는 '0'을 빼주어야 원하는 값이 저장된다.

  • read() 주의점 2) : 공백도 문자임

    문제에서 입력이 공백 단위로 끊어서 읽도록 되어있다.

    read() 가 한 문자를 읽는다고 해서 공백까지 인식하여 분리해 읽는 것은 아님.

    '3 5'를 입력하면 3과 공백이 저장되는것임.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    	public static void main(String[] args) throws IOException{
     
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    //		방법 1 : 입력한 값에 0을 빼준다.
    		int a = br.read() - 48;
    		
    //		방법 2 : '0'은 아스키 코드 값으로 48임. 48을 뺀다.
    		int b = br.read() - 48;
    		System.out.println(a+b);
    	}
    }

    a 에는 3이 저장되지만

    b 에는 '공백' 문자 아스키 코드 값인 35에 48을 뺀 -13이 저장된다.

    위와 같은 read() 메소드의 슬픈 사연들로 10 이상의 값을 받고 싶을 때 쓰기가 매우 복잡해진다.

    BufferedReader 를 쓸 때는 readLine() 으로 쓰는 것이 좋다.

    readLine()은 한 행을 전부 읽기 때문에 공백 단위로 입력해 준 문자열을 공백 단위로 분리해주어야 문제를 풀 수 있다.

문자열 분리 방법에는 두가지가 있다.

  1. StringTokenizer 클래스를 이용하여 분리해주는 방법
  1. split()을 이용하는 방법

성능면에서는 StringTokenizer가 좋다. 단순 규칙으로 문자열을 분리해줄 때 좋다.

StringTokenizer는 java.util 패키지에 있으므로 import 해준 다음 객체를 생성해준다.

👉🏻 방법 3) BufferedReader + StringTokenizer 사용

객체를 생성할 때 StringTokenizer("문자열", 구분자); 를 해주면 된다.

구분된 변수를 꺼낼 때는 차례대로 nextToken();을 해주면 문자열을 반환해준다.

이때 반환시킨 문자열은 반환됨과 동시에 해당 객체에서 사라지게 된다.

그리고 문자열을 반환했으니 Integer.parseInt()로 int 형변환을 시켜준다.

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 br = new BufferedReader(new InputStreamReader(System.in));
		
		String str = br.readLine();
		StringTokenizer st = new StringTokenizer(str, " ");
		int a = Integer.parseInt(st.nextToken());
		int b = Integer.parseInt(st.nextToken());
		
		System.out.println(a+b);
		
		/*
		굳이 String 변수 생성 안하고 입력과 동시에 구분자로 분리해줘도 됨.
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		int a = Integer.parseInt(st.nextToken());
		int b = Integer.parseInt(st.nextToken());
		
		System.out.println(a+b);
		*/
	}
}

👉🏻 방법 4) split

br.readLine()으로 읽어온 것을 split(" ") 하여 공백 단위로 나눠준 뒤 String 배열에 각각 저장하는 방법이다.

쓰기에는 이 방법이 간단하고 보기 편하지만, 나중에 문자열을 다루게 되고 데이터 양이 많아지게 되면 StringTokenizer 보다 성능이 낮아 수행시간 차이가 발생하게 된다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
 
public class Main {
 
	public static void main(String[] args) throws IOException {
		     
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		String[] str = br.readLine().split(" ");
		int a = Integer.parseInt(str[0]);
		int b = Integer.parseInt(str[1]);
		
		System.out.println(a+b);
 
	}
}

'문제풀이 > 백준 입출력과 사칙연산' 카테고리의 다른 글

10171번 : 고양이  (0) 2021.03.03
10172번 : 개  (0) 2021.03.03
1001번 : A-B  (0) 2021.03.03
10998번 : A X B  (0) 2021.03.03
1008번 : A/B  (0) 2021.03.03