본문 바로가기
알고리즘, 문제해결/알고리즘 문제풀이

[프로그래머스] [1차] 다트 게임

by 카펀 2022. 3. 24.

난이도: Level 1

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/17682

 

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

 

programmers.co.kr

 

입력은 단일 문자열 (string)으로 주어집니다.

 

이 문제와 같이 과거에 저장해둔 값을, 가장 최근에 저장한 것을 먼저 꺼내는 경우가 있는 문제에서는 stack 자료구조를 사용하면 좋습니다.

이 문제에서는 연산자 [*, #]을 만났을 때 그러합니다.

 

먼저 저는 주어진 입력을 단위별로 잘라서 vector에 담았습니다. (vector<string> dart)

주어진 입력 dartResult를 검사하고, 아래와 같은 로직을 통해 dart에 담았습니다.

 

string temp = "" 로 선언하고 시작해서, 

  • isOperand 함수를 통해 연산자 [S, D, T, *, #]인지 검사
  • 연산자가 맞다면 temp 값을 dart에 넣고, temp 값 초기화. 이후 연산자를 temp에 넣어 string 형으로 하여 dart에 넣고, temp 값 초기화.
  • 연산자가 아니라면, temp에 해당 값을 추가

위처럼 한 이유는 숫자 10 때문입니다.

다트 점수는 0점에서 10점까지 존재하는데, 10은 char 두 개로 이루어진 숫자이므로, 위의 과정을 통해 하나의 string 원소로써 구분하여 dart에 포함시켰습니다.

 

다음으로, dart를 하나씩 검사하며 아래와 같은 과정을 거쳤습니다. 아래 과정은 stack<int> s를 사용하였습니다.

  • 원소를 isInteger 함수를 통해 정수인지 확인
  • 정수가 맞다면, 다음 원소는 반드시 연산자 [S, D, T]이므로, 연산자까지 확인한 후 powerBy 함수를 통해 제곱 연산을 한 후 s에 투입
  • 정수가 아니라면, 반드시 [*, #] 중 하나.
  • *이라면, 원소를 차례로 두 개 꺼내고, 각 원소에 x 2를 해 준 후, 다시 순서를 맞추어 s에 투입
    • s에 원소가 하나뿐일 때에 대한 예외 처리도 함
  • #이라면, 원소를 하나 꺼내어, -1을 곱한 후 다시 s에 투입

이후 stack 내의 값의 합을 구하여 정답으로 리턴합니다.

 

코드 링크: GitHub

 

GitHub - kchung1995/code_test_personal: 혼자 코딩 테스트 공부를 하며 사용하는 저장소

혼자 코딩 테스트 공부를 하며 사용하는 저장소. Contribute to kchung1995/code_test_personal development by creating an account on GitHub.

github.com

// 문제 링크: https://programmers.co.kr/learn/courses/30/lessons/17682
#include <string>
#include <stack>
#include <vector>
#include <cmath>

using namespace std;

bool isOperand(char c) {
    if (c == 'S' || c == 'D' || c == 'T' || c == '*' || c == '#') return true;
    else return false;
}

bool isInteger(string s) {
    if (s == "10") return true;
    else if ('0' <= s[0] && s[0] <= '9') return true;
    else return false;
}

int powerBy(char c) {
    if (c == 'S') return 1;
    else if (c == 'D') return 2;
    else if (c == 'T') return 3;
    else return -1;
}

int solution(string dartResult) {
    int answer = 0;
    stack<int> s;
    vector<string> dart;
    
    // dartResult를 잘라서 넣음
    string temp = "";
    
    for (int i = 0; i < dartResult.size(); i++) {
        if (isOperand(dartResult[i])) {
            if (temp != "") dart.push_back(temp);
            temp = "";
            temp += dartResult[i];
            dart.push_back(temp);
            temp = "";
        }
        else {
            temp += dartResult[i];
        }    
    }
    
    for (int i = 0; i < dart.size(); i++) {
        if (isInteger(dart[i])) {
            int temp = stoi(dart[i]);
            i++;
            temp = pow(temp, powerBy(dart[i][0]));
            s.push(temp);
        }
        else if (dart[i][0] == '*') {
            int temp1 = 0, temp2 = 0;
            temp1 = s.top();
            s.pop();
            if (!s.empty()) {
                temp2 = s.top();
                s.pop();
                s.push(temp2 * 2);
            }
            s.push(temp1 * 2);
        }
        else if (dart[i][0] == '#') {
            int temp = 0;
            temp += s.top();
            s.pop();
            s.push(-1*temp);
        }
    }
    
    // answer 값 합
    while(!s.empty()) {
        answer += s.top();
        s.pop();
    }
    
    return answer;
}

 

스택을 떠올린다면 쉽게 풀 수 있는 문제라고 생각합니다.

 

댓글