[백준] 5622번 : 다이얼 - JAVA [자바]
https://www.acmicpc.net/problem/5622
5622번: 다이얼
문제 상근이의 할머니는 아래 그림과 같이 오래된 다이얼 전화기를 사용한다. 전화를 걸고 싶은 번호가 있다면, 숫자를 하나를 누른 다음에 금속 핀이 있는 곳 까지 시계방향으로 돌려야 한다. 숫자를 하나 누르면 다이얼이 처음 위치로 돌아가고, 다음 숫자를 누르려면 다이얼을 처음 위치에서 다시 돌려야 한다. 숫자 1을 걸려면 총 2초가 필요하다. 1보다 큰 수를 거는데 걸리는 시간은 이보다 더 걸리며, 한 칸 옆에 있는 숫자를 걸기 위해선 1초씩 더 걸린다.
www.acmicpc.net
-
문제
※ 주의할 점
- 입력은 대문자로 이루어져있다.
- 시간의 합을 구하는 문제다.
- 3가지 풀이 방법을 제시한다.
이 문제를 딱 볼 때 우리가 가장 쉽게 풀 수 있는 방법은 switch - case 문이라고 봤다.
물론 if - else 문으로 풀어도 된다.
그럼에도 switch - case 문을 쓰는 이유는 아무래도 switch - case 문이 특정한 조건이 불규칙적일 때 가독성이 좋다는 점이다.
(물론 필자 입장에서 그렇다는 것..)
풀이 방법으로는 다음과 같다.
- Scanner 로 입력받고 반복문 안에 switch - case 로 조건식을 구성
- BufferedReader 로 입력받고 반복문 안에 switch - case 로 조건식을 구성
- System.in 으로 입력받고 반복문 안에 switch- case 로 조건식을 구성
알고리즘 자체는 크게 다를 것은 없고, 입력방법에 따라 어떻게 차이가 나는지 볼 것이다.
- 풀이
- 방법 1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine();
int count = 0;
int k = s.length();
for(int i = 0; i < k; i++) {
switch(s.charAt(i)) {
case 'A' : case 'B': case 'C' :
count += 3;
break;
case 'D' : case 'E': case 'F' :
count += 4;
break;
case 'G' : case 'H': case 'I' :
count += 5;
break;
case 'J' : case 'K': case 'L' :
count += 6;
break;
case 'M' : case 'N': case 'O' :
count += 7;
break;
case 'P' : case 'Q': case 'R' : case 'S' :
count += 8;
break;
case 'T' : case 'U': case 'V' :
count += 9;
break;
case 'W' : case 'X': case 'Y' : case 'Z' :
count += 10;
break;
}
}
System.out.print(count);
}
}
가장 기본적인 방법이라 할 수 있겠다.
일단 숫자 1 을 걸려면 총 2초가 걸린다고 했고,
가장 첫 문자는 A 이므로 같은 대열에 있는 A, B, C 는 2 부터 시작하기 때문에 3초가 걸린다.
그리고 charAt() 으로 문자열의 문자를 갖고 오기 때문에 " " 가 아닌 ' ' 으로 해주어야된다.
- 방법 2
BufferedReader 을 사용하는 방법이다.
위 알고리즘하고는 별 다를게 없고 입력방법만 달리 구성된다.
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 s = br.readLine();
int count=0;
int k = s.length();
for(int i = 0 ; i < k ; i++) {
switch(s.charAt(i)) {
case 'A' : case 'B': case 'C' :
count += 3;
break;
case 'D' : case 'E': case 'F' :
count += 4;
break;
case 'G' : case 'H': case 'I' :
count += 5;
break;
case 'J' : case 'K': case 'L' :
count += 6;
break;
case 'M' : case 'N': case 'O' :
count += 7;
break;
case 'P' : case 'Q': case 'R' : case 'S' :
count += 8;
break;
case 'T' : case 'U': case 'V' :
count += 9;
break;
case 'W' : case 'X': case 'Y' : case 'Z' :
count += 10;
break;
}
}
System.out.print(count);
}
}
워낙 쉬운 문제라.. 딱히 뭘 설명할 것이 없다..
(슬프지만..) 이 포스팅을 찾는 분들도 거의 없을 듯 싶다.
- 방법 3
방법 2 에서는 BufferedReader 을 사용하여 입력받았었다.
그런데 굳이 Buffer 를 두고 입력받을 필요가 있을까?
생각해보자.
백준 문제는 해당 조건 내에서의 값만 입력받는다. (즉 예외 값이 입력되진 않는다는 의미다.)
그렇기 때문에 따로 생성없이 원시입력을 받아 문자값만 알아내어 count 하면 된다는 것이다.
그리고 조건식은 if - else 를 사용하여 필터링 하는 식으로 해보겠다. (switch - case 를 써도 된다.)
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
int count = 0;
int value;
while(true) {
value = System.in.read();
if(value == '\n') {
break;
}
if(value < 68) count += 3;
else if(value < 71) count += 4;
else if(value < 74) count += 5;
else if(value < 77) count += 6;
else if(value < 80) count += 7;
else if(value < 84) count += 8;
else if(value < 87) count += 9;
else count += 10;
}
System.out.print(count);
}
}
위와 같이 짤 수도 있다.
쉽지 않은가?
A ~ Z 의 경우 int 값으로는 65 ~ 90 이므로 처음 조건에서 필터링 하면서 한 대열씩 검사하는 방법이다.
물론 switch - case 로도 짤 수 있으니 독자 여러분이 자유롭게 선택하면 된다.
- 성능
위에서 부터 순서대로
채점 번호 : 18654037 - System.in.read
채점 번호 : 18654031 - BufferedReader
채점 번호 : 18654025 - Scanner
입력의 경우는 확실히 Scanner 보다는 BufferedReader 또는 System.in.read 가 빠른 걸 볼 수 있다.
- 정리
딱히 이 페이지에서 크게 설명할 것은 없었다.
다만 필자의 고민이 있다면 필자는 Scanner 코드를 계속 제시할지 말지.. 이 것이 고민이다.
처음에는 독자분들의 수준이 워낙 다양하기 때문에 Scanner 로 입력받는 코드도 항상 올렸지만 일단 필자는 Scanner 을 잘 이용하지 않는다.
그래서 아무래도 포스팅 할 때마다 Scanner 을 이용한 코드를 매 번 새로 짜는데, 또한 비효율적인 것도 있고, 지금 단계까지 쭉 풀어보셨다면 아마 BufferedReader 을 모두 쓰실 줄 알 것 같은 생각이 든다.
근데 항상 꼭 그런 것도 아니니.. 고민이다만 일단 당분간은 계속 Scanner 로 입력받는 코드도 올리겠다만 만약에 이 글을 보시는 분들이 계신다면 조언해주신다면 매우 감사하겠다.
'JAVA - 백준 [BAEK JOON] > 문자열' 카테고리의 다른 글
[백준] 1316번 : 그룹 단어 체커 - JAVA [자바] (45) | 2020.03.26 |
---|---|
[백준] 2941번 : 크로아티아 알파벳 - JAVA [자바] (31) | 2020.03.25 |
[백준] 2908번 : 상수 - JAVA [자바] (12) | 2020.03.20 |
[백준] 1152번 : 단어의 개수 - JAVA [자바] (33) | 2020.03.20 |
[백준] 1157번 : 단어 공부 - JAVA [자바] (42) | 2020.03.19 |