c++에는 split이 없으므로 편의상 미리 만들어두었다.
stringstream이 있긴 하지만 원하는 구분자를 설정하기 위해선 결국 getline이란 함수도 추가로 써야하고 string자료형의 token도 같이 운영해줘야 하는 불편함이 있다. 또 stringstream은 어쩐 일인지 일반적인 복사처리에 비해 느리기도 하다. 그래서 다른 언어들 처럼 c++에서도 split을 사용할 수 있도록 미리 만들어 놓았다.
필요 헤더
#include <vector>
#include <string>
#include <ciso646>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
vector<string> Split(string& str, char delimiter = ' ')
{
vector<string> vec;
string buf;
for (auto& ch : str)
{
if (ch == delimiter)
{
if (not buf.empty())
{
vec.push_back(buf);
buf.clear();
}
}
else
{
buf += ch;
}
}
if (not buf.empty())
{
vec.push_back(buf);
}
return vec;
}
|
cs |
+추가로 split후 특정타입으로 변경해줘야하는 경우도 많아 그것에 대한 함수도 만들었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#define sto(x) (x(*)(const string&, size_t*, int))
template <typename T>
vector<T> Split(const string& str, T(*func)(const string&, size_t*, int), char delimiter = ' ')
{
vector<T> vec;
string buf;
for (auto& ch : str)
{
if (ch == delimiter)
{
if (not buf.empty())
{
vec.push_back(func(buf, nullptr, 10));
buf.clear();
}
}
else
{
buf += ch;
}
}
if (not buf.empty())
{
vec.push_back(func(buf, nullptr, 10));
}
return vec;
}
|
cs |
다음과 같이 호출할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
int main(void)
{
int n, m, b;
cin >> n >> m >> b;
cin.ignore();
vector<vector<int>> board;
for (int i = 0; i < n; i++)
{
string buf;
getline(cin, buf);
board.push_back(Split<int>(buf, sto(int)(stoi)));
}
cout << n << ' ' << m << ' ' << b << '\n';
for (auto& row : board)
{
for (auto& el : row)
{
cout << el << ' ';
}
cout << '\n';
}
return 0;
}
|
cs |
'C++ > 함수 및 클래스 창고' 카테고리의 다른 글
[백준] fread 사용법 (0) | 2021.01.19 |
---|