2023. 1. 30. 22:43ใ๐ป C++/C++ TIL
STL ์ ๊ฐ๋จํ๊ฒ ๊ฐ์ฒด๋ฅผ ๋ด๋ '์ปจํ ์ด๋', ๊ฐ์ฒด์ ์ ๊ทผํ๋ '๋ฐ๋ณต์', ๊ฐ์ฒด๋ฅผ ๋ค๋ฃจ๋ '์๊ณ ๋ฆฌ์ฆ'์ผ๋ก ์ด๋ฃจ์ด์ก๋ค๊ณ ํ ์ ์๋ค.
STL ์ปจํ ์ด๋ ์ข ๋ฅ(container)
์ ํ ์ปจํ ์ด๋
- array
- #include <array>
- vector
- #include <vector>
- list
- #include <list>
- forward_list
- #include <forward_list>
- deque
- #include <deque>
์ปจํ ์ด๋ ์ด๋ตํฐ
- stack
- #include <stack>
- queue
- #include <queue>
- priority_queue
- #include <queue>
์ฐ๊ด ์ปจํ ์ด๋
- set (tree)
- #include <set>
- map (tree)
- #include <map>
- unorder_set (hash table)
- #include <unorder_set>
- unorder_map (hash table)
- #include <unorder_map>
STL ์ปจํ ์ด๋์ ๊ณตํต์ ์ธ ํน์ง
1. ๋๋ถ๋ถ ์ปจํ ์ด๋์ ๋ฉค๋ฒ ํจ์๊ฐ ๋์ผํ๋ค
STL์ ์ฅ์ ์ผ๋ก ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ์ปจํ ์ด๋ ๊ต์ฒด๊ฐ ๊ฐ๋ฅํ๋ค
์์ ๋ฃ๊ธฐ / ๋นผ๊ธฐ
- push_front()
- pop_front()
- front()
๋ค์ ๋ฃ๊ธฐ / ๋นผ๊ธฐ
- push_back()
- pop_back()
- back()
์ค๊ฐ์ ๋ฃ๊ธฐ / ๋นผ๊ธฐ
- insert()
- erase()
์ฃผ์) vector ๋ push_front() ๊ฐ ์์!
(์๋ฃ๊ตฌ์กฐ ํน์ฑ์ ์์ชฝ์ ์์๋ฅผ ๋ฃ๋ ๊ฒ์ด ์ฑ๋ฅ์ ์ข์ง ์์ผ๋ฏ๋ก...)
2. ์ ๊ฑฐ์ ๋ฐํ์ ๋์์ ํ์ง ์๋๋ค
pop_front() / pop_back() ํจ์๋ ์ ๊ฑฐ๋ง ํ๊ณ ,
front() / back() ํจ์๋ ๋ฐํ๋ง ํ๋ค!
์ปจํ ์ด๋ ์์ฑํ๋ ๋ฐฉ๋ฒ
#include <iostream>
#include <list>
#include <vector>
int main() {
std::list<int> s1;
std::list<int> s2(10); // 10๊ฐ๋ฅผ 0์ผ๋ก ์ด๊ธฐํ
std::list<int> s3(10, 3); // 10๊ฐ๋ฅผ 3์ผ๋ก ์ด๊ธฐํ
std::list<int> s4{10, 3}; // 2๊ฐ๋ฅผ 10, 3์ผ๋ก ์ด๊ธฐํ
std::list<int> s5 = {10, 3};
std::list<int> s6 = {1,2,3,4,5,6,7};
std::list<int> s7{1,2,3,4,5,6,7};
std::list s8 = {1,2,3,4,5,6,7}; // std::list<int> ๋ก ์ด๊ธฐํ C++17 ๋ถํฐ ์ฌ์ฉ ๊ฐ๋ฅ
}
์์
- 1~10์ผ๋ก ์ด๊ธฐํ๋ vector ๋ง๋ค๊ธฐ
- push_back ํจ์๋ฅผ ์ฌ์ฉํด์ ๋์ 20์ ์ถ๊ฐํ์ธ์
- ๋ชจ๋ ์์๋ฅผ ์ถ๋ ฅํด ๋ณด์ธ์
- [ ] ์ฐ์ฐ์ ์ฌ์ฉ - vector, deque๋ ๊ฐ๋ฅํ์ง๋ง list๋ ๋ถ๊ฐ๋ฅ
- range for ์ฌ์ฉ (for (auto &n : v)) - list ๋ ์ฌ์ฉ ๊ฐ๋ฅ
- ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉ
- ์ ๋ ฌํ๊ณ ํฉ์ ๊ตฌํ๊ณ ๊ฒ์,๋ฑ ๋ณด๋ค ๋ง์ ์์ ํ๋ ค๋ฉด ์๊ณ ๋ฆฌ์ฆ ์ ์์์ผ ํ๋ค
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
v.push_back(20);
for (int i = 0; i <v.size(); i++) {
std::cout << v[i] << std::endl;
}
for(auto& n : v) {
std::cout << n << std::endl;
}
}
STL ๋ฐ๋ณต์ (iterator)
๋ฐฐ์ด ์์์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ
- ๋ฐฐ์ด์ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉ
- ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํด์ ์ ๊ทผ
#include <iostream>
#include <vector>
#include <list>
int main() {
int x[10] = {1,2,3,4,5,6,7,8,9,10};
int *p1 = x;
++p1;
*p1 = 20;
}
๋ฐ๋ณต์ (iterator) ๋?
- ํฌ์ธํฐ์ ์ ์ฌํ๊ฒ ๋์ํ๋ ๊ฐ์ฒด๋ก์, ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ๋ฉด ์ปจํ ์ด๋์ ๋ชจ๋ ์์๋ฅผ ์์ฐจ์ ์ผ๋ก ์ ๊ทผํ ์ ์๋ค.
๋ฐ๋ณต์์ ์ฅ์
- ์ปจํ ์ด๋์ ๋ด๋ถ ๊ตฌ์กฐ(๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ)์ ์๊ด์์ด ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์์์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค
#include <iosteram>
#include <vector>
#include <list>
int main() {
std::list<int> v = {1,2,3,4,5,6,7,8,9,10};
auto p2 = v.begin();
++p2;
*p2 20;
++p2;
std::cout << *p2 << std::endl;
}
๋ฐ๋ณต์์ ๋ฐ์ดํฐ ํ์
์ปจํ ์ด๋ ์ด๋ฆ :: iterator
ex) std::vector<int>::iterator
#include <iostream>
#include <vector>
#include <list>
int main() {
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
// std::vector<int>::iterator p1 = v.begin();
auto p1 = v.begin(); // 1์ ๊ฐ๋ฆฌํด
auto p2 = v.end(); // end๋ 10์ ๊ฐ๋ฆฌํค๋๊ฒ ์๋๋ผ 10 ๋ค์์ ๊ฐ๋ฆฌํค๊ฒ ๋จ
}
์ฃผ์) end() ๋ก ์ป์ ๋ฐ๋ณต์๋ ์ปจํ ์ด๋์ ๋ง์ง๋ง ๋ค์์ ๊ฐ๋ฆฌํจ๋ค
- past the end
- end() ๋ก ์ป์ ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํด์ ์์์ ์ ๊ทผํ๋ฉด ์๋๋ค
- ๋์ ๋๋ฌํ๋์ง ํ์ธํ๋ ์ฉ๋๋ก ์ฌ์ฉํ๋ค.
while(p1 != p2) {
std::cout << *p1 << std::endl;
++ p1;
}
๋ฐ๋ณต์๋ฅผ ๊บผ๋ด๋ ๋ฐฉ๋ฒ
#include <iostream>
#include <vector>
#include <list>
int main() {
// std::list<int> v = {1,2,3,4,5,6,7,8};
int v[10] = {1,2,3,4,5,6,7,8};
// auto p1 = v.begin();
// auto p2 = v.end();
auto p1 = std::begin(v);
auto p2 = std::end(v);
while(p1 != p2) {
std::cout << *p1 << std::endl;
++p1;
}
}
1. ๋ฉค๋ฒ ํจ์ ์ฌ์ฉ
v.begin() / v.end()
** ๋ฐฐ์ด์ ์ฌ์ฉํ ์ ์๋ค
2. ์ผ๋ฐ ํจ์ ์ฌ์ฉ (C++11 ๋ถํฐ)
std::begin(v) / std::end(v)
** ๋ฐฐ์ด์ ์ฌ์ฉํ ์ ์๋ค
์ปจํ ์ด๋์ ๋ชจ๋ ์์๋ฅผ ์ด๊ฑฐํ๋ ๋ฐฉ๋ฒ
1. ๋ฐฐ์ด ์ฐ์ฐ์ ([])
์ฐ์๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฌํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ๊ฒฝ์ฐ๋ง ๊ฐ๋ฅ
vector , array, deque, string
- list ๋ forward_list ๋ [] ์ฐ์ฐ์ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ
for (int i = 0; i < v.size(); i++) {
std::cout << v[i] << std::endl;
}
๋ฐฐ์ด์์๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก v.size() ๋์ std::size(v) ์ฌ์ฉ
2. ๋ฐ๋ณต์ ์ฌ์ฉ
๋ชจ๋ ์ปจํ ์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ
auto p1 = std::begin(v);
while(p1 != std::end(v)) {
std::cout << *p1 << std::endl;
++p1;
}
3. range for ๊ตฌ๋ฌธ ์ฌ์ฉ
๋ชจ๋ ์ปจํ ์ด๋ ์ฌ์ฉ ๊ฐ๋ฅ
for (auto &n : v) {
std::cout << n << std::endl;
}
๋ณต์ฌ๋ณธ์ ๋ง๋ค์ง ์๊ธฐ ์ํด & ๋ฅผ ๋ถ์ฌ์ฃผ์
STL ์๊ณ ๋ฆฌ์ฆ ํน์ง
์๊ณ ๋ฆฌ์ฆ ์ด๋?
์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ ์ฐจ, ๋ฐฉ๋ฒ, ๋ช ๋ น์ด ๋ค์ ์งํฉ
STL ์๊ณ ๋ฆฌ์ฆ ์ด๋?
C++ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ STL ์ด ์ ๊ณตํ๋ ํจ์
- ์ ๋ ฌ, ๊ฒ์, ์์ด, ๋ฑ ๋ค์ํ ์๊ณ ๋ฆฌ์ฆ ๊ตฌํํ ํจ์์ ์งํฉ
STL ์๊ณ ๋ฆฌ์ฆ์ ํน์ง
- ๋ฉค๋ฒ ํจ์๊ฐ ์๋ ์ผ๋ฐ ํจ์ (ํ ํ๋ฆฟ) ์ผ๋ก ์ ๊ณต ๋๋ค
→ ํ๋์ ํจ์(ํ ํ๋ฆฟ)์ผ๋ก ๋ค์ํ ์ปจํ ์ด๋์ ์ฌ์ฉํ ์ ์๋ค (์๋ฃ๊ตฌ์กฐ์ ๋ ๋ฆฝ์ )
→ ๋๋ถ๋ถ ์๊ณ ๋ฆฌ์ฆ์ ํจ์์ ์ธ์์ ๋ฐํ ํ์ ์ผ๋ก ๋ฐ๋ณต์๋ฅผ ์ฌ์ฉ
๋ฐ๋ณต์๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ์ปจํ ์ด๋์ ๋ด๋ถ ๊ตฌ์กฐ์ ์๊ด์์ด ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์์์ ์ ๊ทผํ ์ ์๋ค
- <algorithm> ํค๋๊ฐ ํ์ํ๋ค
- ๋๋ถ๋ถ์ ์๊ณ ๋ฆฌ์ฆ์ด ๋ฐ๋ณต์ ๋ฅผ ํ์๋ก ํ๋ค
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
int main() {
std::list<int> s = {1,2,3,4,5,6,7,8,9,10};
std::vector<int> v= {1,2,3,4,5,6,7,8,9,10};
// s.find(5); X
std::find(begin(v), end(v), 3);
}
๊ฒ์ ์๊ณ ๋ฆฌ์ฆ (find)
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
int main() {
int x[10] = {1,2,3,4,5,6,7,8,9,10};
std::list<int> s = {1,2,3,4,5,6,7,8,9,10};
std::vector<int> v= {1,2,3,4,5,6,7,8,9,10};
// auto p = std::find(begin(v), end(v), 3);
auto p = std::find(x, x+10, 3); // x+9 ๊ฐ ์๋๋ผ x์ ๋ค์์ฃผ์์ธ x+10 ๋ฃ์ด์ผ ํ๋ค
}
- 2๊ฐ์ ๋ฐ๋ณต์ ([first, last), ๊ตฌ๊ฐ) ์ ๊ฒ์ํ ๊ฐ์ ๋ฐ์ ์ ํ๊ฒ์์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ
- first ๋ ๊ฒ์ ๋์์ ํฌํจ๋์ง๋ง, last๋ ๊ฒ์ ๋์์ ํฌํจ๋์ง ์๋๋ค
๋ฐํ๊ฐ
๊ฒ์ ์ฑ๊ณต์ - ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ฐ๋ณต์
์คํจ์ - last // null ์๋!
if ( p == end(v)) {
// ์คํจ
} else {
// ์ฑ๊ณต
std::cout << *p << std::endl;
}
STL ์๊ณ ๋ฆฌ์ฆ๊ณผ ์กฐ๊ฑด์
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector <int> v = {10,9,8,7,6,5,4,3,2,1};
// v ์์์ ์ฒ์ ๋์ค๋ 3์ ๋ฐฐ์๋ฅผ ๊ตฌํด๋ณด์ธ์
auto p = std::find(begin(v), end(v), 3);
std::cout << *p << std::endl;
}
find_if ([first, last),ํจ์)
bool foo(int n) {
return n % 3 = 0;
}
...
auto p = std::find_if(begin(v), end(v), foo);
์กฐ๊ฑด์ predicator
- bool ์ ๋ฐํํ๋ ํจ์, ํจ์ ๊ฐ์ฒด, ๋๋ค ํํ์
- _if ๋ก ๋๋๋ ์๊ณ ๋ฆฌ์ฆ์ ์ ๋ฌ๋์ด ์ ์ฑ ์ผ๋ก ์ฌ์ฉ๋๋ค
auto p = std::find_if(begin(v), end(v), [](int n) { return n % 3 == 0;});
๋๋ง์ ์๊ณ ๋ฆฌ์ฆ ์ข ๋ฅ๋ฅผ ๋ณด๊ณ ์ถ๋ค๋ฉด?
cppreference.com algorithm library ์ฐธ์กฐ
์์
- -1์ ์ ๋ ฅํ ๋ ๊น์ง ์ ๋ ฅ์ ๋ฐ์ vector์ ๋ณด๊ดํด๋ผ → push_back ์ฌ์ฉ
- ์ ๋ ฅํ ๊ฐ ์ค 10 ๋ณด๋ค ํฐ ๊ฐ์ ๋ชจ๋ 0 ์ผ๋ก ๋ณ๊ฒฝํด๋ผ → replace / replace_if ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ
- ๋ชจ๋ ์์์ ํฉ์ ๊ตฌํด์ ์ถ๋ ฅํด๋ผ → accumulate ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ (numeric ํค๋์ ์กด์ฌ)
- vector์ ๋ชจ๋ ์์๋ฅผ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ(sort) ํด์ ์ถ๋ ฅํ์ธ์ → sort ์๊ณ ๋ฆฌ์ฆ + ์กฐ๊ฑด์ ์ฌ์ฉ
- vector์ ๋ชจ๋ ์์๋ฅผ 1๋ก ์ฑ์์ ์ถ๋ ฅํด๋ณด์ธ์ → fill ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
using namespace std;
int main() {
vector<int> v;
int n = 0;
while(1) {
cin >> n;
if (n == -1) break;
v.push_back(n);
}
for (auto &n : v) {
if (n >= 10) n = 0;
}
// replace ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ
replace_if(begin(v), end(v), [](int n) { return n>=10; }, 0);
// ๋ชจ๋ ์์์ ํฉ์ ๊ตฌํ๋ ์๊ณ ๋ฆฌ์ฆ -> accumulate ์๊ณ ๋ฆฌ์ฆ
int sum = accumulate(begin(v), end(v), 0);
// sort (begin(v), end(v)); // ์ค๋ฆ์ฐจ์, ํต์ํธ
sort(begin(v), end(v), [](int a, int b) { return a > b; }); // ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ
// ๋ชจ๋ ์์ 1๋ก ์ฑ์ฐ๊ธฐ
fill(begin(v), end(v), 1);
}