본문 바로가기
Code/baekjoon [ 단계별 ]

백준 단계별 문제 < 입출력 >

by jaeaemin 2022. 1. 12.

[1]입력 : Input

1. Scanner 

Scanner sc = new Scanner(System.in);

 

System.in은 inputStream의 정적 필드이다. 

 - 스트림 : 데이터의 흐름으로 시작점과 끝점이 존재하는 흐름을 의미한다.

     파일 데이터 , 입력 데이터 등이 Stream으로 분류 될 수 있다.

 - InputStream : 입력 값의 시작부터 끝으로, Scanner로 부터 입력받는 데이터 흐름

 - OutputStream : 출력 값의 시작부터 끝

 - 내부 과정에서는 InputStreamReader를 호출하여 StreamDecoder를 호출하여 InputStream을 문자형태로 해석한다.

 - 바이트 단위 데이터를 Charcter 단위 데이터로 변환한다.

 - 이후 next(), netxInt() , nextDouble() ... 을 통해서 데이터를 입력받는다.

 - 정규식 검사를 진행하고 , 스트림의 흐름으로 처리한다.

 

 

2. BufferedReader

BufferedReader br = new BufferedReader(new InputStreamRdader(System.in));

 - InputStreamReader을 통해 바이트 단위의 데이터를 char로 처리한다.

 - Buffer를 이용하여 문자를 쌓아두고 한 번에 문자열처럼 전송한다.

 - br.readline() 메서드는 한줄을 통으로 String 형으로 받아온다.

 - inputStream =[byte data]=> InputStreamReader =[char data]=> BufferReader ==> String 변수

 - 정규식 검사를 하지 않고, byte데이터를 Sting 변수로 처리한다.

 - I/O예외에 발생시 처리가 필요하고 , 사용 후 자원 반납 close() 해주어야 한다.

 

키보드에 입력되는 데이터는 결국 char형식의 데이터들의 모임이다.
System.in으로 입력을 받는다면 바이트 단위로 수신이 되서 UTF-8처리나 다른 처리에 영향을 줄 수 있다.

3. Scanner VS BufferedReader 

Scanner는 스트림 단위 , 문자열은 Space와 Enter를 경계로 입력값을 인식한다. 하나씩 전달하여 입력 데이터가 많으면 더 많은 시간이 소요하게 된다.

BufferedReader는 Enter만 경계로 인식하여 버퍼에 문자열을 쌓아논 후 한번에 전달하여서 속도가 더 빠르고 메모리도 효율적으로 사용한다.

하지만 BufferedReader의 경우 nextInt() 와 같이 타입별로 파싱하는 메서드가 제공되지 않아 Interger.parseInt()의 메서드로 별도 처리를 해우저야 하고,  readLine()을 통해 줄단위로 읽기 때문에 Space로 구분해야하는 경우 split이나 StringTokenizer를 사용해서 문자열을 잘라 주어야 한다. 

 

 

 

[2] 출력 : Output

1. System.out.print/ln()

System.out.prinln("abcd");

 PrintStream(System.out)의 스트림형식 데이터를받아와서 print(), println(), prinf() 방식으로 출력한다.

 

 

2. BufferedWriter

BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(system.out));

bufferedWriter.writer("abcd"); 	// 쓰기용 버퍼에 abcd 문자열을 씀 
bufferedWriter.flush(); 		// 출력
bufferedWriter.newLine(); 		// 새로운 라인 생성
bufferedWriter.close(); 		// 출력

Buffer을 이용하여 출력 스트림을 저장하고 flush or close 시에 출력한다.

 

 

3. System.out.println  vs BufferedReader 

System.out.println 

 -  기본 함수로 사용이 편리하고 구현이 매우 간단하지만 리소스를 많이 소모한다.

BufferedReader 

 - 버퍼에 데이터를 모아 한 번에 출력하여 빠른 속도와 효율적 메모리 사용을 보장한다. 

 - 줄바꿈을 자동으로 처리해주지 않아서 직접 입력해주어야 한다.

 - I/O예외에 발생시 처리가 필요하고 , 사용 후 자원 반납 close() 해주어야 한다.

 

 

 StringBuilder vs StringBuffer

 

 

 

 


[1000]

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

 

import java.util.*; 
public class Main{ 
	public static void main(String args[]){ 
		Scanner sc = new Scanner(System.in); 
		int a, b; 
		a = sc.nextInt(); 
		b = sc.nextInt();
		System.out.println(a+b);
	}
}
입력을 Scanner로 받는 경우
 -Stream 형태로 입력받음
 -nextInt, nextDouble , next 등 메소드로 다음값을 넘겨 받는다

 

 

 

public class Main {
	public static void main(String[] args){
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
 		// 한 행을. 전부 문자열 버퍼로 읽는다.
 		String str = br.readLine(); 
        // 문자열 버퍼의 내용을 공백 기준으로 분리해 토큰화 한다.
		StringTokenizer st = new StringTokenizer(str," ");
        // int형으로 변환한다.
		int a = Int.parseInt(st.nextToken());
		int b = Int.parseInt(st.nextToken());
		
		System.out.println(a+b);
BufferedReader를 쓰는 방법이다
> readLine()은 한 문자열 행을 전부 읽는다.
 > StringTokenizer(str," ")를 통해서 공백 기준 분리했다.
 > split()을 사용해도 가능하다.
        String[] s = br.readLine().split(" ");
 > 그 후 분리된 문자열을 형 변환 시켜준다.

 

 

 

 

[2588] 

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        
        int num1 = x * ((y%100)%10); // 1의 자리
        int num2 = x * ((y%100)/10);
        int num3 = x * ((y/100));
        int num4 = num1 + 10*num2 + 100*num3;
        
        System.out.println(num1);
        System.out.println(num2);
        System.out.println(num3);
        System.out.println(num4);         
    }
}

 

 

 

 

 

+ 대중적인 방법

연산하는 숫자는 문자열로 받아들여서 하나하나 수학적으로 분해하는 것이 아닌 문자 형식으로 분해하는 방법 

import java.util.Scanner;
 
public class Main {
 
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
 
		int A = in.nextInt();
		String B = in.next();
        
		in.close();
 
		System.out.println(A * (B.charAt(2) - '0'));
		System.out.println(A * (B.charAt(1) - '0'));
		System.out.println(A * (B.charAt(0) - '0'));
		System.out.println(A * Integer.parseInt(B));
 
	}
}

이 코드에서 B.charAt(N) - '0'은 무엇인가

B에 해당하는 숫자를 char로 분해했기 때문에 이를 숫자로 바꾸기 위해서 생성한 코드이다.

해당 숫자 "n"을 charAt으로 int형으로 바꾼다면 아스키 코드에 해당하는 값이 나오게 된다. 

하지만 그는 실제 수가 아닌 아스키 코드에 해당하는 번호 이기 때문에 수치를 맞춰줘야할 필요가 있다.

'0'은 아스키 코드에서 처음 시작하는 숫자로 48을 가지고 있다. 

따라서 이 수를 빼주게 되면 아스키코드에 해당하는 숫자를 입력 받을 수 있다.

(ex) 

3=> 아스키 : 53   ,    0=> 아스키 : 48

53 - 48 = 3 

아스키 코드 - 0의 아스키코드는 해당 숫자의 실제 값이 된다.

 

 

 

 

반응형