프로그래머스 - [1차] 다트 게임 (Lv.1)
문제 링크
문제 접근
- dartResult 로 주어진 문자열을 파싱만 잘하면 된다.
- 총 3번의 시도를 하기 때문에 점수판은 길이가 3인 배열로 표현한다.
- 문자열을 탐색하며 숫자 문자인 경우 string 자료형인 str 에 담는다.
- 숫자 뒤에는 바로 S, D, T 의 보너스 문자가 반드시 나오므로 해당 문자가 나오면 str 에 담아둔 숫자 문자열을 정수로 변환한다.
- 보너스 문제에 맞도록 추가 점수 연산을 한다.
- 다음 문자를 확인해서 옵션에 해당하는 스타상(*), 아차상(#) 인 경우 추가 연산을 한다.
- scores 인덱스를 증가시키괴 다음 위 과정을 반복한다.
구현(All Pass)
#include <string>
#include <cctype>
#include <iostream>
#include <vector>
using namespace std;
int solution(string dartResult) {
int answer = 0;
vector<int> scores(3,0);
string str;
int idx = 0;
for(int i=0; i<dartResult.size(); i++){
char ch = dartResult[i];
if(isdigit(ch)){
str.push_back(ch);
}
else if(ch=='S' || ch=='D' || ch=='T'){
int num = stoi(str);
str.clear();
if(ch=='D') num = num*num;
else if(ch=='T') num = num*num*num;
scores[idx] = num;
// 스타상, 아차상 확인
if(i==dartResult.size()-1) continue;
char nCh = dartResult[i+1];
if(nCh=='*'){
if(idx>0) scores[idx-1] = scores[idx-1] * 2;
scores[idx] = scores[idx] * 2;
i++;
}
else if(nCh=='#'){
scores[idx] = scores[idx] * (-1);
i++;
}
idx++;
}
}
answer = scores[0] + scores[1] + scores[2];
return answer;
}
추가 풀이
- 다른 사람의 풀이를 보다가 좋은 방법이 있어서 직접 구현해보았다.
- stringstream 을 활용하여 자료형 별로 입력을 받아 문자열 파싱을 쉽게 구현했다.
구현 - » 연산자를 활용했을 때 분석 (틀린 풀이)
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
int solution(string dartResult) {
int answer = 0;
stringstream ss(dartResult);
vector<int> scores(3, 0);
int num;
char bonus, option;
for(int i=0; i<3; i++){
ss >> num >> bonus >> option;
cout << num << " " << bonus << " " << option << endl;
if(option != '*' && option != '#')
ss.unget(); // 버퍼의 커서를 앞으로 옮긴다.
// 보너스
if(bonus=='D') num = num*num;
else if(bonus=='T') num = num*num*num;
scores[i] = num;
// 옵션
if(option=='*'){
if(i>0) scores[i-1] = scores[i-1] * 2;
scores[i] = scores[i]*2;
}
else if(option=='#'){
scores[i] = scores[i] * (-1);
}
}
answer = scores[0] + scores[1] + scores[2];
return answer;
}
- » 입력 연산자는 개행 문자를 만나면 더이상 입력을 받지 않는다.
- 위 코드에서 stringstream 을 통해 » 연산자로 입력을 받는 경우 개행 문자를 만나면 입력을 받지 않게 되면서 option 변수에 아무런 문자도 들어오지 않게 된다. 따라서, option 변수에는 이전에 저장되어 있던 값이 그대로 사용되는 것이다.
구현 - get() 입력함수로 개행문자, 공백문자도 받아들이도록 함
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
int solution(string dartResult) {
int answer = 0;
stringstream ss(dartResult);
vector<int> scores(3, 0);
int num;
char bonus, option;
for(int i=0; i<3; i++){
ss >> num;
bonus = ss.get();
option = ss.get();
if(option != '*' && option != '#')
ss.unget(); // 버퍼의 커서를 앞으로 옮긴다.
// 보너스
if(bonus=='D') num = num*num;
else if(bonus=='T') num = num*num*num;
scores[i] = num;
// 옵션
if(option=='*'){
if(i>0) scores[i-1] = scores[i-1] * 2;
scores[i] = scores[i]*2;
}
else if(option=='#'){
scores[i] = scores[i] * (-1);
}
}
answer = scores[0] + scores[1] + scores[2];
return answer;
}
- get() 함수는 공백문자, 개행문자를 포함하여 문자를 버퍼에서 읽어오고, 커서를 다음으로 옮긴다.
- unget() 함수는 버퍼의 커서를 앞으로 한칸 옮긴다.
Leave a comment