https://school.programmers.co.kr/learn/courses/30/lessons/120902
#include <string>
#include <vector>
using namespace std;
int solution(string str) {
int answer = 0;
int sign=1;
vector<int> v;
string tmp;
for(auto c: str){
if(c==' '){
if(tmp!=""){
v.emplace_back(sign*stoi(tmp));
tmp="";
}
}
else if(c=='-'){
sign=-1;
}
else if(c=='+'){
sign=1;
}
else{ //그냥 글자일때
tmp+=c;
}
}
v.emplace_back(sign*stoi(tmp));
for(auto c: v) answer+=c;
return answer;
}
위의 풀이가 내가 작성해서 제출한 풀이이고, 이 풀이를 생각할때, 뭔가 이 문자열 전체를 받아들여서 하는 방법이 있었던것 같은데 생각이 나지 않아서 경우들을 나누어서 위와 같은 코드를 작성해서 프로그램을 만들었다.
위와 같은 풀이를 제출한뒤, 다른 사람의 풀이를 보니까 내가 처음에 이 문제를 접했을때 생각했던데로 전체적인 string에서 흐름을 통해서 문제를 해결하는 방법으로 푼 방법이 가장 위에 있었으며, 거기서 사용한 방법은 stringstream을 이용하는 풀이였다.
아직 나에게 있어서 stringstream을 이용하는 잘 생각이 나지 않는듯 하다.
다른 사람의 풀이에서 가장 위에 올라와 있는 풀이를 첨부해보면,
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int solution(string my_string) {
int answer = 0;
stringstream ss;
ss.str(my_string);
ss>>answer;
char ch;
int tmp = 0;
while(ss)
{
if(ch == '+')
{
answer += tmp;
}
else if(ch == '-')
{
answer -= tmp;
}
ss >> ch >> tmp;
}
return answer;
}
이와 같은 코드를 볼 수 있는데, 위의 코드에 대한 해석을 돕기 위해서 지피에 해당 코드에 대한 분석을 요구하면
=====================
이 코드는 문자열 my_string
에 포함된 숫자와 연산자를 파싱하여 계산하는 프로그램입니다. 주어진 문자열에는 연속된 숫자와 '+' 또는 '-' 연산자가 포함되어 있습니다.
stringstream
객체인ss
를 생성하고, 이를 문자열my_string
으로 초기화합니다.ss
를 사용하여 첫 번째 숫자를answer
에 저장합니다. 이는 문자열에서 첫 번째 숫자를 읽어온 것입니다.char
타입의 변수ch
와int
타입의 변수tmp
를 선언합니다. 이들은 현재 처리 중인 연산자와 숫자를 저장하는 데 사용됩니다.while
루프를 사용하여 문자열 파싱을 수행합니다. 파싱은 다음과 같이 동작합니다:ch
에 '+' 또는 '-' 연산자를 읽어옵니다.tmp
에 다음 숫자를 읽어옵니다.- 읽어온 연산자와 숫자를 기반으로
answer
를 갱신합니다. '+' 연산자면answer += tmp
, '-' 연산자면answer -= tmp
를 수행합니다. - 다음 연산자와 숫자를 읽어올 때까지 반복합니다.
- 루프를 빠져나가면 최종 계산 결과가
answer
에 저장되어 반환됩니다.
#이 코드는 문자열에서 수식을 읽어와 계산하는 기본적인 방법을 보여줍니다. 문자열 파싱 및 연산은 입력에 따라 다양한 예외 상황을 처리해야 할 수 있으므로 실제 응용 프로그램에서는 더 강력한 오류 처리와 안정성을 추가해야 할 것입니다.
===================================
위와 같은 답변을 얻을 수 있다.
위에서 얻을 수 있는 정보들을 통해서 stringstream을 이용해서 위와 같은 문제를 해결하는 방법에 대해서 기록해보자면,
stringstream ss; 형태로 객체를 선언하고,
ss.str(my_string); 형태로, str() 함수를 이용해서 my_string 이라는 이름으로 주어지는 string으로 stringstream 객체를 초기화,
그리고 나서
먼저 ss>>answer; 을 통해서 가장 앞에 있던 숫자를 answer에 저장하고, 그 뒤에 이제 순차적으로 처리를 한다는걸 알 수 있다.
이와 관련해서 추가적으로 어떤식으로 변해가는지에 대해서 검색해보면,
=====================ss >> answer
를 실행한 후에는 ss
스트림 내에서 현재 읽지 않은 나머지 내용이 남아 있습니다. ss
스트림은 입력 데이터를 순차적으로 읽어 나가는데, ss >> answer
는 ss
에서 데이터를 읽어 answer
에 저장한 것입니다. 따라서 현재 ss
스트림의 내용은 answer
를 읽은 후의 상태입니다.
예를 들어, "123+456"
이라는 문자열을 ss
에 넣고 ss >> answer
를 실행하면, answer
에는 123
이 저장되고, ss
에는 "123+456"
에서 "123"
을 제외한 "+"
와 "456"
부분이 남게 됩니다. 이제 ss
에서 "+"
와 "456"
을 읽을 수 있게 됩니다.
#계속해서 ss >> ch >> tmp
를 통해 "+"
와 "456"
을 읽어오고, ch
에는 "+"
가, tmp
에는 456
이 저장됩니다. 이후 루프에서 연산을 수행하고 나면, ss
는 "+"
와 "456"
을 모두 읽어서 내용이 더 이상 없게 됩니다.
======================
이와 같은 정보를 볼때, stringstream이라는 객체에서 ch와 tmp에 순차적으로 ss>>ch>>tmp; 을 이용해서 계속 값들을 저장해가면서 stringstream에서 다음 값들로 넘어가면서 위와 같은 연산을 수행한다는걸 알 수 있다.
위의 코드와 유사하지만 stringstream을 사용하는 다른 풀이가 있는데, 이 코드 또한 꽤 깔끔한 느낌을 주고, !ss.eof() 을 이용하는 형태로 while 문을 돌리는 코드가 있어서 첨부해본다.
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int solution(string my_string) {
stringstream ss(my_string);
char op; int num;
int result;
ss >> result;
while (!ss.eof()) {
ss >> op;
ss >> num;
if (op == '+') result += num;
else result -= num;
}
return result;
}
https://cplusplus.com/reference/sstream/stringstream/stringstream/
'알고리즘 > 프로그래머스' 카테고리의 다른 글
Lv 0. 숫자 찾기 (0) | 2023.09.28 |
---|---|
Lv 0. 배열의 유사도 - 효율적인 검색을 고려한 rb트리를 이용한 풀이. c++에서는 set *다시 풀어보기* (0) | 2023.09.27 |
Lv 0. 가장 큰 수 찾기 iterator을 이용해서 배열의 인덱스를 찾으려면, distance() 함수를 사용해보자 *다시 풀어보기* (0) | 2023.09.26 |
Lv 0. 편지 (0) | 2023.09.26 |
Lv 0. 약수 구하기. *다시 풀어보기* (0) | 2023.09.26 |