백준 10871 문제를 풀다가 발견한 System.in.read() 코드! 10871번: X보다 작은 수 (acmicpc.net)
저는 BufferedReader을 사용해서 문제를 풀었는데 시간을 훨씬 단축시킨 사람들 코드를 보니 System.in.read()을 사용하고 있었습니다. 그런데 이해가 잘 가지 않아서 혹시 저와 같은 사람이 있을까봐 글을 씁니다.
우선 System.in.read()는 문자 char타입인 문자 하나를 입력값으로 받고 그 문자에 대응하는 아스키 코드를 int값으로 출력하는 코드입니다.
이 문제는 공백을 포함한 긴 문자열인 '10 5 \n'를 입력값으로 받은 후 System.in.read()로 읽어들여야 하는데요 System.in.read()는 '문자 하나'만을 입력으로 받습니다. 그럼으로 System.in.read()를 간단하게만 보면 두가지 문제가 생깁니다.
- 10을 어떻게 입력값으로 받을까
(10은 1이라는 문자와 0이라는 문자로 이루어진 2가지 문자입니다. 읭?? 싶으신 분들은 아스키코드를 검색검색 고~~~) - 숫자 하나만 읽고 끝나는 것이 아니고 \n를 만날때까지 계속 입력값을 읽어들여야 함
이 문제를 해결하기 위해선 버퍼에 대한 이해가 있어야 합니다.
간단하게 그려봤는데요...ㅎㅎ
컴퓨터와 키보드 사이엔 입력스트림이란게 있습니다. 키보드에서 '10 5 \n'를 입력하면 입력스트림에 '10 5 \n'가 줄을 쭉 서서 System.in.read()라는 버스를 기다려요! 이 버스는 문자 1개가 최대 정원이라 처음 '1'을 태우면 '0 \n'는 기다려야 합니다.
그리고 입력이 끝난다고 해서 버스줄이 사라지지 않고 다음 System.in.read() 버스가 오면 '0'이 버스를 타고 컴퓨터로 가요.
class Main{
int num = read();
System.out.println("num"+num);
//int baseNum = read();
//System.out.println("baseNum"+baseNum);
}
public static int read() throws IOException {
int totalValue=0;
int input;
while(true){
input = System.in.read();
System.out.println("input"+(input-48));
//input -48은 아스키를 고려한 것입니다.
if(input=='\n' || input==' ') {
System.out.println("return"+(totalValue));
return totalValue;
} else {
totalValue =
(totalValue*10)
+ (input-48);
}
}
}
<결과값>
'10 5\n'를 입력했을 때의 결과값입니다. '10 5\n'가 입력 스트림에 들어갔고 System.in.read()버스가 첫 문자인 1을 데리고 컴퓨터로 들어갔어요. 그 다음 두번째 문자인 0을 데리고 컴퓨터로 들어가고 마지막 문자인 ' ' 를 데리고 컴퓨터로 들어왔습니다! 그리고 컴퓨터로 들어온 모든 문자열을 이렇게 저렇게 만져서 10이라는 숫자를 리턴하고 num에 숫자 10이 저장되었네요. 이건 제가 공백이나 엔터를 만나기 전까지 이 메소드에 머무르게 하기 위해 반복문에 가두어 놨기 때문입니다.
기억해야 할 부분은 반복문이 끝나고 리턴문으로 Main에 돌아갔다고 버스 대기줄이 사라지는 건 아니라는 것입니다.
<주석 처리된 부분을 해제하고 실행 했을 때의 결과값>
'10 5\n'에서 '10 '가 입력스트림에서 컴퓨터로 들어가고 종료되었더라도 '5\n'라는 버스 대기줄은 여전히 존재하고 다시 System.in.read() 라는 버스가 운행하면 나머지 숫자들이 컴퓨터로 이동하는 것을 확인할 수 있습니다.
System.in.read() 코드를 이해하는데 도움이 되었으면 좋겠네요!
'개발 공부 > Java' 카테고리의 다른 글
[자바다] 뒤늦게 적어보는 java 환경변수 세팅하는 법 (0) | 2022.10.27 |
---|---|
[자바다] 자바에서 for문이 while문의 속도 차이와 그 이유 (아마...) (0) | 2022.09.27 |
[자바다] int string등 각 타입에서 'equals' 와 '==' 구별하는 법 (0) | 2022.09.22 |
[자바다] 클래스, 객체, 인스턴스란 무엇일까? 각 개념의 차이점 (0) | 2022.09.19 |
[자바다] 윈도우와 맥에서의 캐리지리턴(\r), 라인피드(\n) (0) | 2022.09.15 |
댓글