백준 1001
- 문제
- 풀이
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String num = sc.nextLine();
int result = 0;
int num1 = 0;
int num2 = 0;
for (int i = 0; i < num.length(); i++) {
if (num.charAt(i) - 48 > 0 && num.charAt(i) - 48 < 10) {
if (num1 == 0) {
num1 = num.charAt(i) - 48;
} else {
num2 = num.charAt(i) - 48;
}
} else {
continue;
}
}
result = num1 - num2;
System.out.println(result);
}
}
1001번 문제를 풀려고 하니, A+B
에서 A-B
가 된 것 뿐인데
변수 두 개와 if/else
문이 추가됐다. 더하기 연산에서 빼기 연산으로
바꾸는 간단한 작업이였는데, 꽤 복잡해졌다.
궁금해서 구글에 백준 1001
번 문제를 검색해봤다.
그리고 내가 Scanner에 대해 잘 모르고 있었다는 사실을 깨달았다.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("첫번째 정수를 입력하세요 : ");
int num1 = sc.nextInt();
System.out.print("두번째 정수를 입력하세요 : ");
int num2 = sc.nextInt();
System.out.println(num1 + "과 " + num2 + "의 합은 " + (num1 + num2) + "입니다.");
}
}
그동안 Scanner를 위와 같은 형식
으로 밖에 사용해보지 않았다.
따라서 nextInt()라는 메소드가 공백
이 얼마나 들어가던,
엔터키
가 얼마나 들어가던 상관 없이 입력받은 정수를 차례로
리턴한다는 사실을 알지 못했던 것이다.
nextInt()
를 사용하면 1000번 문제, 1001번 문제는 아래와
같은 4줄의 코드
로 작성할 수 있다.
- 풀이 2
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
System.out.println(num1 - num2);
}
}
보다시피 입력 받은 정수 사이에 공백이 얼마나 포함되건, 엔터가 얼마나
포함되건 상관 없이 입력한 정수만 변수에 담아 계산이 이루어지고 있다.
이뿐만이 아니라 위 링크의 블로그를 보면 Scanner
는
BufferedReader 보다
성능이 현저하게 떨어지기
때문에
아래와 같이 짠 코드를 볼 수 있다.
- 풀이 3
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 num1 = Integer.parseInt(st.nextToken());
int num2 = Integer.parseInt(st.nextToken());
System.out.println(num1 - num2);
}
}
블로그에 작성된 정보에서 필자가 이해한 부분만
정리해보자.
1. System.in 은 InputStream이라는 클래스의 객체이다.
-> InputStream은 byte 단위로 읽는 역할을 하는 스트림이다.
-> 스트림은 그냥 데이터가 흘러가는 통로이다.
2. InputStreamReader는 바이트 단위로 읽은 데이터를 문자로 변경하는
역할을 하는 클래스이다. 따라서 매개변수로 InputStream 타입을 받는다.
3. BufferedReader는 데이터을 직렬화 하는 역할의 클래스이다.
-> String으로 만들어준다고 생각하면 된다.
즉, new BufferedReader(new InputStreamReader(System.in)
이라고 쓰인 코드는 System.in을 통해 입력받은 데이터를 byte 단위로
읽어오고, InputStreamReader를 통해 문자로 변환한 뒤,
BufferedReader를 통해 해당 데이터를 직렬화해서 버퍼에 쌓아놓는
것이다.
실제로 br.readLine이 실행되는 과정을 생각해봤다.
블로그를 통해 알게된 내용으로 br.readLine이 실행
됐을 시 이렇게 실행되지 않을까?
라는 생각으로
정리해봤다.
- 풀이 4
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 num1 = Integer.parseInt(str[0]);
int num2 = Integer.parseInt(str[1]);
System.out.println(num1 - num2);
}
}
BufferedReader를 사용한 것은 동일하다.
StringTokenizer가 아닌 split을 통해 구현
한 모습이다.
추가적으로 split은 공백이 하나일 시에만 위의 코드가 정상 작동한다.
물론 공백이 두개라면 두번으로 split할 수 있겠지만 공백이 하나일 수도
두개일 수도 세개일 수도 있다면 구현에 어려움이 생길 것 같다.
반면 Scanner의 nextInt와 StringTokenizer는 공백의 숫자와
상관없이 데이터를 추출해준다.
- 결과 비교
BufferedReader + split (풀이 4)
BufferedReader + StringTokenizer (풀이 3)
Scanner의 nextInt() (풀이 2)
본인이 짠 코드 (풀이 1)
생각보다 Scanner와 nextInt를 사용한 코드와
내가 짠 코드의 속도의 차이는 안난다. 하지만
1. 조건문 + 반복문 사용으로 코드량이 늘어나면 차이가 날 것 같다.
2. Scanner, nextInt를 사용했을 시 코드량이 현저하게 적다.
3. 가독성도 전자가 좋다고 생각한다.
이런 이유들을 추정해봤을때 Scanner를 사용하는게 더 좋아보인다.
더 나아가 Scanner를 사용했을때와 BufferedReader를
사용했을 경우를 비교해보자. 결과 비교의 이미지에서 보다시피
Scanner를 사용했을 때 보다 BufferedReader를 사용했을
경우 속도가 훨씬 빠르다. 이유는 Scanner는 많은 정규식 등을
검사하는 과정이 있는 반면 BufferedReader는 그런 과정이
없으며, Buffer에 데이터를 쌓아두었다가 반환하기 떄문이다.
따라서 BufferedReader를 사용하는게 더 좋아보인다.
더 나아가 StringTokenizer와 split을 비교해보자.
위 결과에서는 유의미한 차이가 없지만 데이터가 많아지면
많아질 수록 StringTokenizer가 성능상 우위를 점한다고 한다.
따라서 StringTokenizer를 사용하는게 더 좋아보인다.
마지막으로 내가 잘한점을 남기고 마치겠다.
내 코드는 0 < A, B < 10의 조건을 신경썼고 나머지 코드는
이를 신경쓰지 않았다. 따라서 다른 코드들은 A와 B가 0과
10 사이의 수가 아니라도 정상 동작한다. (잘했어~)
Author And Source
이 문제에 관하여(백준 1001), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@onestep/algorithm-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)