[백준] 2908번 : 상수 - JAVA [자바]
https://www.acmicpc.net/problem/2908
2908번: 상수
문제 상근이의 동생 상수는 수학을 정말 못한다. 상수는 숫자를 읽는데 문제가 있다. 이렇게 수학을 못하는 상수를 위해서 상근이는 수의 크기를 비교하는 문제를 내주었다. 상근이는 세 자리 수 두 개를 칠판에 써주었다. 그 다음에 크기가 큰 수를 말해보라고 했다. 상수는 수를 다른 사람과 다르게 거꾸로 읽는다. 예를 들어, 734와 893을 칠판에 적었다면, 상수는 이 수를 437과 398로 읽는다. 따라서, 상수는 두 수중 큰 수인 437을 큰 수라고 말할
www.acmicpc.net
-
문제

입력받은 문자열을 뒤집을 수 있는지가 point 인 문제다.
※ 주의할 점
- 두 수는 공백을 기준으로 구분되며 세 자릿수로 고정되어있다.
- 입력받은 두 수를 뒤집은 값 중 더 큰 값을 출력해야한다.
- 3가지 풀이방법을 제시한다.
기본적으로 이 문제는 풀이방법이 정말 많다.
배열을 이용할 수도 있고 StringBuilder 의 reverse() 메소드를 이용하여 문자를 뒤집을 수도 있으며 입력 자체를 한 문자씩 읽어들여 수식을 완성시키는 방법도 있다.
이번 풀이 방법의 3가지는 다음과 같다.
- Scanner + StringBuilder.reverse()
- BufferedReader + StringBuilder.reverse();
- System.in.read() + 수학 연산
- 풀이
- 방법 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(); in.close(); A = Integer.parseInt(new StringBuilder().append(A).reverse().toString()); B = Integer.parseInt(new StringBuilder().append(B).reverse().toString()); System.out.print(A > B ? A : B); } }
가장 기본적인 방법이라 할 수 있겠다.
아마 가장 궁금할 부분은 StringBuilder 이지 않을까 싶다.
먼저 StringBuilder 는 문자열을 다루는 클래스로 많이 쓰이고 있는데, 여기서 reverse() 라는 아주 좋은 메소드를 포함하고 있다.
즉, 위를 사용하기 위해 먼저 StringBuilder 생성과 동시에 append() 라는 메소드에 값을 넣어준다.
이때 append() 로 넣어진 값은 타입이 StringBuilder 라는 타입으로 변환된다.
그리고 그렇게 저장된 수를 reverse() 라는 메소드를 통해 저장되어있던 문자열을 뒤집는다. 그리고 StringBuilder 타입을 문자열로 반환시키기 위해 toString() 을 써주면 끝이다.
그리고 문자열로 반환시켰으니 Integer.parseInt() 로 String 을 int 로 타입을 변경시키면 끝이다.
그렇게 뒤집힌 값은 출력에서 A 와 B 중 큰 값이 출력되도록 하면 끝난다.
- 방법 2
BufferedReader 을 사용하는 방법이다.
이 방법은 위 코드랑 별반 다를 것은 없다만 변경되는 것은 문자열 분리를 위한 StringTokenizer 가 추가된다는 점과, append() 를 쓰지 않고 바로 객체생성할 때 문자열을 넣을 수 있다는 점이다.
(물론 StringTokenizer 대신 String 배열을 선언하여 split() 메소드로 분리해주어도 된다. 어찌되었던 분리된 두 문자열이 필요하다는 점에서는 같다.)
아래 코드를 보자.
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)); StringTokenizer st = new StringTokenizer(br.readLine()," "); int A = Integer.parseInt(new StringBuilder(st.nextToken()).reverse().toString()); int B = Integer.parseInt(new StringBuilder(st.nextToken()).reverse().toString()); System.out.print(A > B ? A:B); } }
보면 객체를 생성할 때 문자열 인자를 바로 넣어줄 수 있다는 점이 다르다.
아까 Scanner 을 사용했을 때는 int 타입으로 받았기 때문에 객체를 생성할 때 append() 메소드를 써야했지만 만약 넣어주려는 인자가 String 타입이면 append() 를 사용할 필요가 없다.
- 방법 3
이 방법은 약간 꼼수라면 꼼수인 방법이다..
BufferedReader 말고 가장 원시 입력인 System.in.read() 를 사용하는 방법이다.
어차피 입력되는 수는 세 자릿수로 고정되어있기 때문에 더욱 빠르고 쉽게 짤 수 있다.
그리고 read() 메소드는 한 자리씩 반환되기 때문에 문자열을 뒤집을 필요 없이 다음과 같은 수식으로 누적해주면 된다.
예로들어 A 라는 변수에 369 라는 수를 뒤집어서 저장하려면 다음과 같이 하면 된다.
int A = 0; A += input(); A += input() * 10; A += input() * 100;
( 약식 코드이니 input() 은 입력한다는 의미정도로만 알면 된다. )
한 문자씩 3개를 읽어들여 위 수식을 적용하면 A 에는 입력된 세 자릿수가 뒤집힌 값으로 저장될 것이다.
즉, 아래와 같이 짜면 된다.
import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { int A = 0; int B = 0; A += System.in.read() - 48; A += (System.in.read() - 48)*10; A += (System.in.read() - 48)*100; System.in.read(); // 공백 B += System.in.read() - 48; B += (System.in.read() - 48)*10; B += (System.in.read() - 48)*100; System.out.println(A > B ? A : B); } }
- 성능

위에서 부터 순서대로
채점 번호 : 18565956 - System.in.read() ( 방법 3 )
채점 번호 : 18565954 - BufferedReader ( 방법 2 )
채점 번호 : 18565952 - Scanner ( 방법 1 )
입력의 경우는 확실히 Scanner 보다는 BufferedReader 가 빠르나 워낙 짧은 문자열이다보니 BufferedReader 와 System.in.read() 의 차이는 거의 없는 듯 하다.
- 정리
이번 문제는 문자열을 뒤집을 수 있는가가 관건인 문제였다.
만약 문자열을 뒤집을 줄 안다면 매우 쉬운 문제였을 것이다.
( 사실 세 자릿수라 뒤집을 줄 모른다 하더라도 금방 짤 수 있었을 것이다.)
'JAVA - 백준 [BAEK JOON] > 문자열' 카테고리의 다른 글
[백준] 2941번 : 크로아티아 알파벳 - JAVA [자바] (31) | 2020.03.25 |
---|---|
[백준] 5622번 : 다이얼 - JAVA [자바] (29) | 2020.03.24 |
[백준] 1152번 : 단어의 개수 - JAVA [자바] (33) | 2020.03.20 |
[백준] 1157번 : 단어 공부 - JAVA [자바] (42) | 2020.03.19 |
[백준] 2675번 : 문자열 반복 - JAVA [자바] (22) | 2020.03.19 |
댓글을 사용할 수 없습니다.