728x90

 

문제설명

입력 & 출력

나의 풀이

import java.util.*;

class Solution {
    public int solution(String dartResult) {
        int idx = 0;
        int[] scores = new int[3];
        StringBuilder sb = new StringBuilder();
        
        for(int i = 0 ; i < dartResult.length(); i++){
            char ch = dartResult.charAt(i);
            if(Character.isDigit(ch)){//숫자
                sb.append(ch);
            }else if(Character.isLetter(ch)){ //알파벳
                int n = Integer.parseInt(sb.toString());
                sb.setLength(0); //다음 숫자를 위해서 초기화
                
                //보너스
                if(ch == 'S'){ 
                    scores[idx++] = (int)Math.pow(n,1);
                }else if(ch == 'D'){
                    scores[idx++] = (int)Math.pow(n,2);
                }else{
                    scores[idx++] = (int)Math.pow(n,3);
                }
            }else{ // 옵션
                if(ch == '*'){ //스타상
                    if(idx >= 2){
                        scores[idx - 2] *= 2;
                    }
                    scores[idx - 1] *= 2;
                }else{ //아차상 
                    scores[idx - 1] *= -1;
                }
            }
            
        }

        return Arrays.stream(scores).sum();
    }
}

 

이번 문제는 3번의 다트 기회가 주어지고, 각 기회마다 점수|보너스|[옵션]으로 주어진 문자열을 고려하여 최종 점수를 계산하면 되는 문제입니다.

 

먼저 for문 밖에서는 나중에 각 다트 기회마다 점수를 기록할 scores배열을 선언합니다. 그리고 해당 점수 배열의 인덱스를 조작할 idx변수를 초기화해 줍니다.

 

그리고 중요한 부분인 StringBuilder를 초기화해 줍니다. 이는 나중에 보너스와 옵션 말고 점수를 따로 뽑아서 저장할 변수입니다.

 

입력받은 문자열만큼의 반복문을 돌려주고, charAt() 메서드를 사용하여 각 문자요소에 접근을 해줍니다. 그리고 Character클래스의 isDigit() 메서드와 isLetter() 메서드를 사용하여 해당 문자 요소숫자인지, 알파벳인지 판별을 해줍니다.

 

만약 숫자라면 StringBuilder의 append() 메서드를 사용하여 sb문자열에 추가를 해줍니다. 

 

boolean isDoubleDigit = false; // 10 처리를 위한 플래그

        for (int i = 0; i < dartResult.length(); i++) {
            char ch = dartResult.charAt(i);

            if (Character.isDigit(ch)) {
                if (isDoubleDigit) {
                    currentNumber = 10; // 이전 문자가 '1'이었을 때 '0'이 나왔을 경우 10 처리
                    isDoubleDigit = false;
                } else {
                    currentNumber = Character.getNumericValue(ch);
                    if (ch == '1') {
                        isDoubleDigit = true; // 다음 문자가 '0'이 나왔을 때 10 처리 준비
                    }
                }

 

StringBuilder나 숫자를 저장하지 않으면 위와 같이 숫자가 10일 때 처리해 주는 로직이 필요합니다.

 

마저 설명을 하자면 isDigit() 메서드를 사용하여 숫자를 모두 저장하고, 알파벳일 때 sb에 저장된 숫자 문자를 가져와서 Integer.parseInt() 메서드를 사용하여 숫자로 캐스팅을 해줍니다.

 

그리고 다음 다트 기회 때 점수를 계산하기 위하여 setLength() 메서드를 사용하여 0으로 초기화를 해줍니다.

 

이제 보너스를 계산해야 합니다. 보너스는 문제설명에서 나왔듯이 해당 문자에 대해서 Math.pow() 메서드를 사용하여 제곱을 해주고 점수 배열에 저장을 해줍니다.

 

마지막으로 옵션을 계산하는 조건문에서 스타상일 때는 해당 점수까지의 모든 점수를 2배를 해줍니다.

 

이때 만약에 idx값이 2보다 크거나 같다는 의미는 점수를 계산할 때 idx++ 즉 증감연산자를 사용했기 때문에 현재 옵션을 계산하는 조건문에서는 idx값이 증가되어 다음 점수를 가리키고 있습니다. 따라서 현재 점수와 이전 점수도 2배를 해줘야 합니다.

 

그리고 아차상일 때는 현재 점수를 마이너스해줍니다. 마지막으로 각 다트 기회마다 보너스와 옵션도 계산된 점수 배열 scores를 모두 더한 값을 출력해야 하는 데 이때 Steam API의 sum() 메서드를 사용하여 점수를 더해줍니다.

 

return scores[0] + scores[1] + scores[2];

 

물론 위와 같이 다트 기회가 3으로 정해져 있기 때문에 해도 되지만 Stream API의 메서드를 활용해 보았습니다. :)

 

참고 ❗️

 

[JAVA] 입출력, BufferedReader, StringTokenizer, StringBuilder 알아보기

Java로 코딩테스트를 보거나 입력을 사용해야 할 때 Scanner 클래스를 사용하면 편리하지만 속도가 느리다는 단점이 있습니다. 그렇기 때문에 속도가 빠른 BufferReader 클래스를 사용을 하면 시간복

pixx.tistory.com

 

[JAVA] Stream API에 대해 알아보기 _ Stream 최종 연산(집계) (4/5)

Stream의 객체를 구성하고자 할 때 "Stream 생성 → 중간 연산→ 최종 연산"의 세 단계의 과정을 통해서 Stream의 구성이 이루어집니다.  이번 포스팅에서는 Stream 생성 후 생성된 스트림을 필터링하

pixx.tistory.com

 

[JAVA] Character.isLetter() & Character.isDigit() 메서드 알아보기

Java에서 문자열을 다룰 때, 종종 특정 문자가 알파벳인지 숫자인지 여부를 판별해야 할 때가 있습니다. 이를 위해 자바는 유용한 메서드 중 하나로 isLetter 메서드와 isDigit를 제공합니다. 이 글에

pixx.tistory.com