코드 저장소

공부에는 끝이 없다!

JAVA/코딩 테스트

백준 문제 풀이 - 문자열 단계 - 5622번 다이얼(브론즈 2)

VarcharC2K 2023. 8. 16. 21:09

문자열 단계도 이제 거의 막바지이다.

이번 문제는 다이얼 전화기에 각 알파벳에 해당하는 숫자가 있고, 문자열이 들어왔을 때 전화를 걸기 위해 최소 시간을 구하는 코드를 만드는 문제였다.

이 문제도 사람마다 푸는 방식이 많이 달랐는데, 대부분의 사람들은 다음과 같이 각 알파벳 별로 케이스를 만들고 케이스에 해당하는 카운트를 만들어 문제를 해결하였다.

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);
	}
}

하지만 보면 보다시피 지나치게 코드가 길어 보기가 매우 불편하다.

그나마 짧게 만든 코드가 각 알파벳을 아스키 코드값으로 바꾸고 범위를 지정하여 카운트를 추가 하는 방식이였는데,

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
String a = sc.next();

int result = 2;


for(int i=0;i<a.length();i++){
    if(i != 0 && i != a.length()-1){
        result+= 1;
    }
int aaa = a.charAt(i) -65 + 65;
    if(aaa <= 67 && aaa >= 65){
        result+= 2;
    }else if(aaa <= 70 && aaa >= 68){
        result += 3;
    }else if(aaa <= 73 && aaa >= 71){
        result += 4;
    }else if(aaa <= 76  && aaa >= 74){
        result += 5;
    }else if(aaa <= 79 && aaa >= 77){
        result += 6;
    }else if(aaa <= 83 && aaa >= 80){
        result += 7;
    }else if(aaa <= 86 && aaa >= 84){
        result += 8;
    }else if(aaa <= 90 && aaa >= 87){
        result += 9;
    }
}

        System.out.println(result);
    }
}

 

 

해당 풀이는 각 아스키 코드값 사이에 들어오는 값으로 해당 케이스의 시간을 결과값에 더하여 출력하는 방식이다.

 

나는 조금 다른 방식으로 풀었는데, 우선 문제를 보고 다이얼의 구멍 갯수를 보니 각 구멍을 배열로 변환하였을때 결과값이 배열의 인덱스와 일치하는것을 알았다. (잘보면 1전에 구멍이 2개있고 1의 시간은 2인데, 전체 다이얼의 구멍을 배열이라고 생각했을때, 각 숫자의 시간은 인덱스 값과 일치한다)

 

그래서 다이얼이라는 기준 배열을 만들고, 들어오는 문자열의 문자를 contains 메서드로 포함하는 경우에 result에 다이얼의 인덱스 값을 집어 넣도록 하였다.

import java.util.*;
import java.io.*;

class Main{
    public static String s,temp;
    public static int result;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        s = br.readLine();
        result = 0;       
        br.close();
        
        String[] dial = {"","","","ABC","DEF","GHI","JKL","MNO","PQRS","TUV","WXYZ"};
        for(int i =0; i < s.length(); i++){
            temp = String.valueOf(s.charAt(i));
            for(int j = 3; j<dial.length;j++){
                if(dial[j].contains(temp)){
                    result += j;
                }
            }
        }
        
        System.out.println(result);
    }
}

코드를 보면 기준 배열인 dial이 있고, 각 문자열의 위치가 문제의 다이얼의 숫자의 값과 일치하는 것을 알 수 있다.

그리고 입력된 문자열만큼 반복하며 기준 배열에 들어있는지 검증하고, 들어있는 경우 해당 인덱스 값을 result에 더하여 출력한다.

 

처음에 생각할때는 아무래도 2중 for문을 사용하는 만큼 단일 for문 보다 느리지 않을까 생각했는데, 검사 결과를 보니 오히려 더 빠르게 풀린 것을 확인 할 수 있었다.

아무래도 2중 for문 자체가 그렇게 도는 횟수가 많지 않아서 시간적으로 그렇게 크게 손해가 없지 않았나 생각해 본다.

개인적으로는 빠르고 간략한 코드를 만드는 방법이 아니였나 생각해본다.