문제
세 개의 자연수 A, B, C가 주어질 때 A × B × C를 계산한 결과에 0부터 9까지 각각의 숫자가 몇 번씩 쓰였는지를 구하는 프로그램을 작성하시오.
예를 들어 A = 150, B = 266, C = 427 이라면 A × B × C = 150 × 266 × 427 = 17037300 이 되고, 계산한 결과 17037300 에는 0이 3번, 1이 1번, 3이 2번, 7이 2번 쓰였다.
입력
첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다.
출력
첫째 줄에는 A × B × C의 결과에 0 이 몇 번 쓰였는지 출력한다. 마찬가지로 둘째 줄부터 열 번째 줄까지 A × B × C의 결과에 1부터 9까지의 숫자가 각각 몇 번 쓰였는지 차례로 한 줄에 하나씩 출력한다.
코드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int c = sc.nextInt();
String str = Integer.toString(a*b*c);
int[] count = new int[10];
for(int i=0; i<str.length(); i++){
for(int j=0; j<10; j++){
if( str.charAt(i) == Character.forDigit(j, 10) ) count[j]++;
}
}
for(int i=0; i<10; i++){
System.out.println(count[i]);
}
}
}
풀이 시도
1. (a*b*c)를 10의 배수로 나누고 나머지를 구해 각 자리수를 1의 자리수가 나올 때까지 구하고 구해진 각각의 수를 count해서 배열에 넣어야겠다고 생각했다. 잘 안 됐다.
2. 만약 (a*b*c)를 String 형태로 얻는다면, StringTokenizer를 이용해서 숫자를 하나씩 끊어줄 수 있지 않을까 생각했다. 하지만 StringTokenizer는 지정된 문자열로 String을 구분한다. 구분자 없이 연속된 숫자들을 끊을 수 없었다. 패스.
3. (a*b*c)를 문자열로 얻는다면 0~9 역시 char로 변환시키고 String str = Integer.toString(a*b*c) 안에서 일치하는 char를 반환하는 방법이 있지 않을까 생각했다.
3-1. 처음엔 indexOf() 메서드를 생각했다. 하지만 indexOf()는 해당 문자/문자열이 처음으로 등장하는 위치를 반환한다.
3-2. 오만 삽질 끝에 charAt() 메서드를 생각해냈다. charAt() 메서드는 지정한 인덱스에 해당하는 문자를 반환한다. for문으로 문자열의 인덱스들을 0~9와 비교하고, 일치하면 해당 숫자의 배열 값에 ++을 해주도록 코드를 작성했고 풀이에 성공했다.
코드가 더러운 건 말할 것도 없고 삽질도 삽질이다............ String으로 받아야겠다까지 생각하는 데도 오래 걸렸지만, 부족한 복습으로 적용할 메서드를 한번에 떠올리지 못한 것이 제일 크고 질긴 엿이다. 왜 나는 공부를 대충 해서 스스로 엿을 찾아 먹는가.................... 반성하고 일단 복습부터 더 밀리기 전에 틈틈이 하기로 한다.
풀이 개선
1. BufferedReader가 성능이 더 좋다는 건 알지만 아직 낯선 친구라 손이 잘 안 간다.
2. 배열의 출력은 향상된 for문으로 가능하다. 속도 상으로는 차이가 없는 것 같은데 일단 익숙해지려고 노력해본다.
for(int result : count){
System.out.println(result);
}
3. 처음 생각을 조금 틀면 문자열으로 변환 없이 풀 수도 있었다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int a = Integer.parseInt(reader.readLine());
int b = Integer.parseInt(reader.readLine());
int c = Integer.parseInt(reader.readLine());
int mul = a*b*c;
int[] count = new int[10];
while(mul!=0){
count[mul%10]++;
mul/=10;
}
for(int result : count){
System.out.println(result);
}
}
}
3-1. 1의 자리 수부터 차례로 올라가면서 count 하기로 한다.
3-2. 1의 자리수에 있는 수를 count 했다면 10으로 나누어서 한자리씩 줄여나가면서 10으로 나눈 몫이 0이 될 때까지 연산을 계속한다.
3-3. 배열의 초기값은 0이므로 count 되지 않은 인덱스로는 0이 반환된다. (if int[] arr)
reference.
사고 흐름이 많이 힘들었다. 전반적으로 빙빙 돌고 돌아서 푼 것 같아서 많이 민망하고 어이없고 자괴감 든다. 멍청한 건 어떻게 고쳐야 하는지 감이 안 온다. 그래도 다음엔 이런 걸로 다시 삽질 하지 말고 이번 기회에 확실하게 기억하라고 삽질한 것까지 기록해둔다.
'problem solving > baekjoon' 카테고리의 다른 글
java/ 백준 11286 절댓값 힙 (0) | 2022.07.21 |
---|---|
java/ 백준 5622 다이얼 (0) | 2022.05.15 |
java/ 백준 15552 빠른 A+B (0) | 2022.05.07 |