문제설명
입력 & 출력
나의 풀이
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의 메서드를 활용해 보았습니다. :)
참고 ❗️
'Coding Test > 프로그래머스' 카테고리의 다른 글
[프로그래머스] Lv.2 의상 (HashMap, getOrDefault, Java) (0) | 2024.06.15 |
---|---|
[프로그래머스] Lv.2 튜플 (LinkedHashSet, replaceAll, substring, Java) (0) | 2024.06.15 |
[프로그래머스] Lv.1 소수 만들기 (브루트 포스 알고리즘, Java) (1) | 2024.06.14 |
[프로그래머스] Lv.2 n^2 배열 자르기 (2차원 배열 ➡️ 1차원 배열 변환 행열 접근 공식,Java) (1) | 2024.06.13 |
[프로그래머스] LV.1 완주하지 못한 선수 (HashMap, StringBuilder, getOrDefault, Java) (1) | 2024.06.11 |