Lv 0. 컨트롤 제트

https://school.programmers.co.kr/learn/courses/30/lessons/120853

 

#include <string>
#include <vector>
#include <stack>

using namespace std;

stack<int> stk;

int solution(string s) {
    int answer = 0;
    int plus=1;
    int tmp=0;
    for(auto c: s){
        if(isdigit(c)){
            tmp=tmp*10+c-'0';
        }
        else if(c=='-'){
            plus=-1;
        }
        else if(c==' '){
            stk.push(plus*tmp);
            plus=1;
            tmp=0;
        }
        else{//c=='Z'
            stk.pop();
        }
    }
    if(s[s.size()-1]!='Z') stk.push(plus*tmp);
    while(!stk.empty()){
        answer+=stk.top(); stk.pop();
    }
    return answer;
}

내가 작성하고 제출한 코드는 위와 같은데, 다른 사람의 풀이를 보니까 stringstream 과 stoi 함수를 사용한 풀이가 있어서 첨부해보겠다. 

 

#include <string>
#include <vector>
#include <stack>
#include <sstream>

using namespace std;

int solution(string s) {
    int answer = 0;

    stringstream ss;
    ss.str(s);

    stack<int> st;

    int t = 0;
    string tmp = "0";
    while(ss>>tmp)
    {
        if(tmp == "Z")
        {
            st.pop();
        }
        else
        {        
            t = stoi(tmp);
            st.push(t);
        }
    }

    while(!st.empty())
    {
        answer += st.top();
        st.pop();
    }

    return answer;
}

위에 첨부한 프로그램이 <sstream> 헤더를 추가하고 stringstream ss 을 선언한뒤에 stringstream과 stoi() 함수를 이용한 풀이이고, 

이때에 stringstream에 대해서 더 알아보기 위해서 gpt에 질문하여 얻은 내용을 첨부해보면, 

주어진 코드는 문자열 `s`에서 정수와 "Z" 문자를 처리하고, 스택을 사용하여 계산한 결과를 반환하는 
C++ 프로그램입니다. 코드의 핵심 부분은 `stringstream`과 `while(ss >> tmp)` 루프입니다.

1. **stringstream (`stringstream ss`)**: `stringstream`은 문자열을 스트림으로 변환하는 데 
사용되며, C++에서 텍스트 데이터를 파싱하고 처리하는 데 유용합니다. `stringstream` 객체 `ss`는 
문자열 `s`를 스트림으로 변환합니다.

2. **while 루프 (`while(ss >> tmp)`)**: 이 루프는 `ss`에서 `tmp`로 공백으로 구분된 문자열을 
반복적으로 읽어옵니다. 각 반복에서 `ss >> tmp`는 `ss`로부터 하나의 문자열을 읽어와서 `tmp`에 저장합니다.

   - `ss >> tmp`에서 `>>` 연산자는 스트림에서 값을 읽어오는 연산을 수행합니다.
   - 스트림에서 값 읽기를 시도하다가 더 이상 읽을 값이 없으면 루프가 종료됩니다.

3. **문자열 처리**: `tmp`로 읽어온 문자열이 "Z"인 경우 스택에서 값을 팝하고, 그렇지 않으면 정수로 
변환하여 스택에 푸시합니다.

4. **스택 처리**: 문자열을 모두 처리한 후에는 스택에 남은 값들을 팝하고, 이를 `answer`에 누적하여 
최종 결과를 계산합니다.

간단한 예제를 통해 코드의 동작을 설명하겠습니다:

```cpp
#include <iostream>
#include <string>

int main() {
    std::string input = "5 Z 2 3 Z 1";
    int answer = solution(input);
    std::cout << "Answer: " << answer << std::endl; // Answer: 9
    return 0;
}
```

이 예제에서 `stringstream`은 "5 Z 2 3 Z 1" 문자열을 공백을 기준으로 분리하여 각 숫자와 "Z" 문자를 
읽어와 스택에 처리하고, 최종 결과는 9가 됩니다.

결국 위와 같은 프로그램을 만드는데 가장 중요한건 stringstream에 대한 이해와 활용으로 보여지고, 그에 해당하는 정보들을 얻기 위해서 gpt에 검색해서 정보를 얻어보면 아래와 같은 내용들을 얻을 수 있었다. 

 

C++의 `std::stringstream` 클래스는 문자열 데이터를 스트림으로 처리하는 데 사용되는 
표준 라이브러리 클래스입니다. `stringstream`은 문자열에서 데이터를 읽고 쓸 수 있도록 하는 중요한 
도구로, 주로 문자열 파싱, 문자열 데이터의 형식 변경, 데이터 출력 등에 활용됩니다.

`std::stringstream`은 `<sstream>` 헤더 파일에 정의되어 있으며, `<iostream>` 헤더 파일과 
마찬가지로 입력 및 출력 스트림과 관련된 기능을 제공합니다. 아래는 `std::stringstream`의 주요 특징과 
사용법에 대한 설명입니다:

1. **스트림 인터페이스**: `std::stringstream`은 스트림(`std::istream` 및 `std::ostream`) 
클래스의 인터페이스를 따릅니다. 따라서 `>>` 및 `<<` 연산자를 사용하여 데이터를 입력 및 출력할 수 있습니다.

2. **문자열 파싱**: `std::stringstream`은 문자열에서 원하는 형식으로 데이터를 파싱할 때 매우 편리합니다. 
예를 들어, 문자열에서 정수, 실수 또는 다른 데이터 유형으로 데이터를 읽을 수 있습니다.

    ```cpp
    std::string data = "42 3.14 Hello";
    int intValue;
    double doubleValue;
    std::string stringValue;

    std::stringstream ss(data);
    ss >> intValue >> doubleValue >> stringValue;

    std::cout << intValue << " " << doubleValue << " " << stringValue << std::endl;
    ```

3. **데이터 형식 변경**: `std::stringstream`을 사용하여 데이터를 다른 형식으로 변환할 수 있습니다. 
예를 들어, 숫자를 문자열로 변환하거나, 반대로 문자열에서 숫자로 변환할 수 있습니다.

    ```cpp
    int number = 42;
    std::stringstream ss;
    ss << number;

    std::string numberAsString = ss.str();
    ```

4. **스트림 초기화**: `std::stringstream` 객체를 초기화하고 데이터를 스트림에 입력하려면 `str()` 
함수를 사용합니다.

    ```cpp
    std::stringstream ss;
    ss.str("Hello, World!");

    std::string data;
    ss >> data; // "Hello,"
    ```

5. **스트림 조작**: `std::stringstream` 객체는 스트림 조작 함수를 사용하여 형식 지정 및 조작을 
수행할 수 있습니다. 예를 들어, `std::setw`, `std::setprecision`, `std::fixed` 등의 함수를 
사용하여 출력 형식을 지정할 수 있습니다.

    ```cpp
    #include <iomanip>

    double pi = 3.14159265359;
    std::stringstream ss;
    ss << std::fixed << std::setprecision(2) << pi;

    std::string formattedPi = ss.str(); // "3.14"
    ```

`std::stringstream`은 문자열을 효율적으로 파싱하고 처리하는 데 사용되며, 데이터 형식 변환 및 스트림 
조작에도 유용합니다. 이 클래스는 많은 문자열 처리 작업을 간편하게 수행할 수 있도록 도와줍니다.

stringstream 이라는것은 ' '을 이용해서 흐름을 나누어서 각각의 내용들을 사람이 이해하기 위해 필요한 부분들로 나누어서 사용할 수 있게 해주는 것이고, 거기에 내장되어 있는 함수들을 잘 사용하면 손쉽게 string으로 이루어진 정보들을 나누어서 원하는 형태로 자르고 변형하고 하는 형태의 코드를 작성할 수 있게 해주는 것으로 볼수있겠다. 

현재까지는 주로 c++로 알고리즘 문제 해결 위주로 사용하고 있고, 학습하던 형태의 알고리즘 문제들이 스트링을 다루는 형태가 적었기 때문에 stringstream에 대해서는 익숙치 않은데, 이런형태의 타입이 있고 이렇게 활용해서 (stoi(), str() 등을 활용해서) string으로 주어지는 것들을 마음껏 다룰 수 있다는것을 알아두도록 하자. 

 

  Comments,     Trackbacks