hoon's bLog

Java 프로그래머스 다트게임 자바 본문

코딩테스트/프로그래머스

Java 프로그래머스 다트게임 자바

개발한기발자 2022. 6. 23. 13:38
반응형

문제 출처 : https://programmers.co.kr/learn/courses/30/lessons/17682

 

코딩테스트 연습 - [1차] 다트 게임

 

programmers.co.kr


지은아, 네가 여기서 왜 나와?...

아이유에 속아

문제를 잊지말자...

[나의 풀이]

- 문자열과 숫자를 구분하여 점수 산출 방식을 정해야 함.

- 각 문자열에 대한 조건을 구분하여, 보너스 점수 계산하는 로직 구성

public class Solution {
    public int solution(String dartResult) {
        int answer = 0;
        int[] score = new int[3];                   // 각 게임별 점수를 담을 배열
        char[] charArr = dartResult.toCharArray();  // 다트점수를 각각 문자열로 담을 배열
        int idx = -1;                               // 조건에 따라 조절되는 index 별도 선언
        
        for (int i=0; i<charArr.length; i++) {
            // n번째 라운드 점수가 0~9인 경우
            if (charArr[i] >= '0' && charArr[i] <= '9') {
                idx++; // 점수 배열 인덱스를 맞춰주기 위한 증가
                score[idx] += Integer.parseInt(String.valueOf(charArr[i])); // 점수 추가
                if (charArr[i] == '1' && charArr[i+1] == '0') { //10점인 경우
                    //이미 들어가 있는 index 제거
                    score[idx] -= Integer.parseInt(String.valueOf(charArr[i]));
                    score[idx] = 10;
                    i++;    		//10일때는 다음 문자열 건너뛰기 위한 증가
                }
            } else if (charArr[i] == 'D') {
                score[idx] = (int) Math.pow(score[idx],2);
            } else if(charArr[i] == 'T') {
                score[idx] = (int) Math.pow(score[idx],3);
            } else if (charArr[i] == '*') { // 이전 라운드와 현재 라운드에 2배
                if (idx > 0) score[idx-1] *=2;
                score[idx] *= 2;
            } else if (charArr[i] == '#') { // 현재 라운드에 -1 곱하기
                score[idx] *= -1;
            }
        }
        answer = score[0] + score[1] + score[2];
        return answer;
    }
}

코드는 정상적으로 동작한다.

하지만 역시 내 코드라서 였을까?

for문 안의 여러 조건문이 영 맘에 들지 않는다...

다른 분들은 어떻게 푸셨을까?

[다른 사람의 풀이-1]

import java.util.Stack;

public class Solution17 {
    public int solution(String dartResult) {
        //점수를 담을 Stack 선언
        Stack<Integer> stack = new Stack<>();
        int sum = 0;
        for (int i = 0; i < dartResult.length(); ++i) {
            char c = dartResult.charAt(i);
            //Character형으로 변환후 isDigit() 메서드로 숫자인지 여부 확인
            if (Character.isDigit(c)) {
                sum = (c - '0');
                if (sum == 1 && i < dartResult.length() - 1 && dartResult.charAt(i + 1) == '0') {
                    sum = 10;
                    i++;
                }
                stack.push(sum);
            } else {	//숫자 아닌 경우
                int prev = stack.pop();
                if (c == 'D') {
                    prev *= prev;
                } else if (c == 'T') {
                    prev = prev * prev * prev;
                } else if (c == '*') {
                    if (!stack.isEmpty()) {
                        int val = stack.pop() * 2;
                        stack.push(val);
                    }
                    prev *= 2;
                } else if (c == '#') {
                    prev *= (-1);
                }
                stack.push(prev);
            }
        }
        int totalScore = 0;
        while (!stack.isEmpty()) {
            totalScore += stack.pop();
        }
        return totalScore;
    }
}

[다른 사람의 풀이-2]

public class Solution {
    static int[] sum = new int[3];
    
    static int solution(String msg){
        String reg = "([0-9]{1,2}[S|T|D][*|#]{0,1})";

        Pattern p = Pattern.compile(reg+reg+reg);
        Matcher m = p.matcher(msg);
        m.find();

        for(int i=1; i<=m.groupCount(); i++){
            Pattern p1 = Pattern.compile("([0-9]{1,2})([S|T|D])([*|#]{0,1})");
            Matcher m1 = p1.matcher(m.group(i));
            m1.find();
            sum[i-1] = (int)Math.pow(Integer.parseInt(m1.group(1)), getpow(m1.group(2)));
            setting(i,m1.group(3));
        }
        
        return(sum[0]+ sum[1]+ sum[2]);
    }
    
    static void setting(int idx, String msg){
        if(msg.equals("*")){
            sum[idx - 1] *= 2;
            if(idx > 1 ) sum[idx - 2] *=2;
        }else if(msg.equals("#")) sum[idx - 1] *=-1 ;
    }
    
    static int getpow(String mag){
        if(mag.equals("S")) return 1; 
        else if(mag.equals("D")) return 2;
        else return 3;
    }
}

[정리]

- 다른 분의 첫 번째 풀이로는, Character형으로 변환하여 요소들을 Stack에 담고 꺼내어 연산도 가능!

- 첫번째 풀이에서는 Stack 보다도 문자열에 대한 연산을 기억해야 함!

- 두 번째 풀이로는 Pattern 클래스와 Matcher 클래스의 메서드를 활용하여 검증하는 것! 나온 김에 Pattern 클래스의 메서드 정리!!

Pattern 클래스의 메서드
- compile(String regex) : 주어진 정규표현식으로부터 패턴을 만듭니다.
- matcher(CharSequence input) : 대상 문자열이 패턴과 일치할 경우 true를 반환합니다.
- asPredicate() : 문자열을 일치시키는 데 사용할 수 있는 술어를 작성합니다.
- pattern() : 컴파일된 정규표현식을 String 형태로 반환합니다.
- split(CharSequence input) : 문자열을 주어진 인자 값 CharSequence 패턴에 따라 분리합니다.
Matcher 클래스 주요 메서드
- matches() : 대상 문자열과 패턴이 일치할 경우 true 반환합니다.
- find() : 대상 문자열과 패턴이 일치하는 경우 true를 반환하고, 그 위치로 이동합니다.
- find(int start) : start위치 이후부터 매칭 검색을 수행합니다.
- start() : 매칭 되는 문자열 시작위치 반환합니다.
- start(int group) : 지정된 그룹이 매칭되는 시작위치 반환합니다.
- end() : 매칭되는  문자열 끝 다음 문자 위치 반환합니다.
- end(int group) : 지정돼 그룹이 매칭 되는 끝 다음 문자 위치 반환합니다.
- group() : 매칭 된 부분을 반환합니다.
- group(int group) : 매칭된 부분 중 group번 그룹핑 매칭 부분 반환합니다. 
- groupCount() : 패턴 내 그룹핑한(괄호 지정) 전체 개수를 반환합니다.

- 코딩의 꽃이라 할 수 있는 정규표현식..... 찾다가 자주 쓰는 것만 정리하고 추후 정규표현식을 따로 정리해야 할 듯하다!

- 일단 자주 쓰는 애들이라도 정리!

정규식 표현 설명
^[0-9]*$ 숫자
^[a-zA-Z]*$ 영문자
^[가-힣]*$ 한글
\\w+@\\w+\\.\\w+(\\.\\w+)? E-Mail
^\d{2,3}-\d{3,4}-\d{4}$ 전화번호
^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$ 휴대전화번호
\d{6} \- [1-4]\d{6} 주민등록번호
^\d{3}-\d{2}$ 우편번호

개인 피셜 난이도 : ★☆☆

자바는 알아가면 알아갈수록 점점 더 어려워지는 것 같다.

그래도 문제를 푸는 재미와,

새로운 기술들과 풀이들을 알가는 재미가 나름 쏠쏠하다!ㅎㅎㅎ

33살이라는 세월이 무색하지 않도록,

계속해서 갈고닦는,

그런 개발한 기발자 되기를!ㅎㅎㅎㅎ

 

끝.

728x90
반응형