쉼표(,)로 구분된 여러 개의 정수가 포함된 문자열이 있다고 가정해 보겠습니다. 이때 각 정수를 분리해 내고, 정수 하나씩 서로 다른 줄에 출력해야 합니다. 이러한 작업은 C++의 stringstream(sstream 헤더)을 사용하면 손쉽게 해결할 수 있습니다.
stringstream은 C++ 표준 라이브러리에서 제공하는 문자열 기반 스트림 클래스입니다. 스트림에서 데이터를 꺼낼 때는 추출 연산자(>>)를, 스트림에 데이터를 넣을 때는 삽입 연산자(<<)를 사용하며, str() 함수를 이용하면 내부 문자열 버퍼의 내용을 설정하거나 가져올 수 있습니다.
예를 들어 입력 문자열이 s = "56,9,85,256,47"이라면 출력은 다음과 같습니다.
56
9
85
256
47
해결 알고리즘
이 문제는 다음 단계를 따라 해결할 수 있습니다.
- take_int(string str) 함수를 정의합니다.
- 입력 문자열로 초기화한 stringstream 객체
ss를 생성합니다. - 결과를 저장할 정수 벡터
result를 선언합니다. ss에서 정수를 성공적으로 추출하는 동안 다음을 반복합니다.- 추출한 값
tmp를 result의 끝에 추가합니다. - 스트림에서 문자 하나(쉼표)를 읽어 건너뜁니다.
- 추출한 값
- result를 반환합니다.
- 입력 문자열로 초기화한 stringstream 객체
- main 함수에서 다음을 수행합니다.
integers = take_int(s)를 호출하여 정수 목록을 얻습니다.- i가 0부터 integers의 크기 미만일 때까지 반복하며 각 정수를 한 줄에 하나씩 출력합니다.
동작 원리
여기서 핵심은 while(ss >> tmp) 조건입니다. 스트림에서 정수 추출에 성공하면 조건이 참이 되어 반복이 계속되고, 더 이상 읽을 정수가 없으면 거짓이 되어 루프가 자연스럽게 종료됩니다. 또한 정수와 정수 사이에는 항상 쉼표가 있으므로, 정수를 하나 읽은 뒤 ss >> ch;로 쉼표를 소비해 주어야 다음 반복에서 정수를 정확하게 읽을 수 있습니다.
예제 코드
아래 구현 예제를 통해 더 자세히 이해해 보겠습니다.
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
vector<int> take_int(string str) {
stringstream ss(str);
vector<int> result;
char ch;
int tmp;
while(ss >> tmp) {
result.push_back(tmp);
ss >> ch;
}
return result;
}
int main(){
string s = "56,9,85,256,47";
vector<int> integers = take_int(s);
for(int i = 0; i < integers.size(); i++)
cout << integers[i] << "\n";
}
입력
56,9,85,256,47
출력
56
9
85
256
47
이 알고리즘은 문자열을 한 번만 순회하므로 시간 복잡도는 O(n)입니다. 참고로 구분자가 쉼표가 아닌 공백이나 다른 문자인 경우에도 동일한 원리로 처리할 수 있으며, C++11 이후 환경이라면 getline()과 stoi()를 조합하거나 정규식(regex)을 활용하는 방법도 좋은 대안이 될 수 있습니다.