프로그래머스 코딩테스트 입문 문제인 컨트롤 제트 풀이를 진행해보겠습니다.
저는 c++의 stack을 이용해서 풀었으나, sstream 도 쓰시는 것을 권장합니다.
https://school.programmers.co.kr/learn/courses/30/lessons/120853#
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr


문제 설명
문제 설명을 드리자면, "1 2 Z 3"일때 실제로는 "1 2 -2 3"을 더하도록 만들어주세요! 라는 뜻입니다.
Z가 오면 '가장 최근에 더했던 숫자를 기억하는 것'이 관건인데, 저는 stack 이 바로 떠올랐어요.
스택에 차례로 데이터를 넣고 가장 최근 데이터를 pop하면 되니까요.
코드 설명
#include <string>
#include <vector>
#include <stack>
#include <iostream>
#include <string>
using namespace std;
int solution(string s) {
int answer = 0;
stack<int> sum;
//position of the next space for slicing
size_t pos;
string number=s;
먼저 숫자를 차곡차곡 저장할 stack 과, 다음 공백의 위치를 나타내는 pos, 그리고 slice 된 string을 나타내는 number를 만들어 줬습니다.
//append space for checking end of string.
s.append(" ");
여기다 s.append(" ")를 저는 해 줬는데요, 이렇게 하면 마지막 문자까지 포함해서 slicing을 할 수 있게 됩니다.
이 로직이 빠지면 아래 코드에서 마지막 element가 포함이 되지 않는 문제가 발생했어요.
추후에 기술하겠지만, 프로그래머스에서 제공하는 코드가 조금 더 좋은 거 같습니다.
//find next space until no slices left.
while((pos = s.find(' ')) != string::npos)
{
//target string
number= s.substr(0,pos);
//remainder of the string
s=s.substr(pos+1,s.size()-1);
이후에는 while로 돌면서, 다음 공백이 npos,즉 not found, invalid position일 때까지 반복합니다.
배열의 시작부터~ 첫 공백이 나오는 지점까지 자르면, 첫 단어를 뽑을 수 있어요.
그리고 중요한 건, s를 update해 주는 건데, substr 자체가 기존 source string을 수정하기 않기 때문에
number 이후 remainder(추출 후 나머지) 스트링을 업데이트하는 과정이 필요합니다.
if(number=="Z")
{
//pick the top value of the stack and invert to push in it.
int last= sum.top();
sum.push(-last);
}
//case for number.
else
{
int n= stoi(number);
sum.push(n);
}
생각외로 stack 로직 부분은 굉장히 심플해요.
오히려 string stream을 처리하는 부분이 더 중요했습니다.
참고로 stack pop을 할 필요도 없었어요.
왜냐면 기존 element도 계산에 포함되기 때문에 그냥 다 넣어줬습니다.
while(sum.size()>0)
{
int n=sum.top();
sum.pop();
answer +=n;
}
return answer;
그리고 마지막은 sum에 있는 값을 다 털어주면 됩니다.
프로그래머스 정석 풀이
int solution(string s)
{
stringstream ss(s);
string tmp = "";
stack<int> st;
int t = 0;
while (ss >> tmp)
{
cout << tmp << ",";
if (tmp == "Z")
{
st.pop();
}
else {
t = stoi(tmp);
st.push(t);
}
}
int answer = 0;
while (!st.empty())
{
answer += st.top();
st.pop();
}
return answer;
}
이번엔 정석 풀이도 함께 가져왔어요. sstream을 이용해서, str parsing을 훨씬 간단하게 구현합니다.
>> operator는 공백을 기준으로 stream을 구분하기 때문에, ss>>tmp만 활용해도 substr보다 훨씬 간단해요.
그리고 아까 위에서
s.append(" ") 하는 부분이 있었죠? 공백을 기준으로 find pos를 하게 되면, 마지막 element가 항상 남게 되었습니다.
그래서 이 방식이 훨씬 깔끔하고, 논리적으로 예외가 없는 neat한 코드라고 생각합니다.
나머지는 동일합니다!
그럼 오늘도 즐거운 코딩하시길 바랍니다.
댓글