STL ์ปจํ ์ด๋
STL ์ปจํ ์ด๋¶
1. STL์ด๋?¶
STL(Standard Template Library)์ C++ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํต์ฌ์ผ๋ก, ์๋ฃ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ์ ์ ๊ณตํฉ๋๋ค.
STL ๊ตฌ์ฑ์์¶
| ๊ตฌ์ฑ์์ | ์ค๋ช |
|---|---|
| ์ปจํ ์ด๋ | ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์๋ฃ๊ตฌ์กฐ |
| ๋ฐ๋ณต์ | ์ปจํ ์ด๋ ์์ ์ํ |
| ์๊ณ ๋ฆฌ์ฆ | ์ ๋ ฌ, ๊ฒ์ ๋ฑ ๋ฒ์ฉ ํจ์ |
| ํจ์ ๊ฐ์ฒด | ํจ์์ฒ๋ผ ๋์ํ๋ ๊ฐ์ฒด |
2. vector¶
๋์ ํฌ๊ธฐ ๋ฐฐ์ด์ ๋๋ค. ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋ฉ๋๋ค.
๊ธฐ๋ณธ ์ฌ์ฉ¶
#include <iostream>
#include <vector>
int main() {
// ์์ฑ
std::vector<int> v1; // ๋น ๋ฒกํฐ
std::vector<int> v2(5); // ํฌ๊ธฐ 5, 0์ผ๋ก ์ด๊ธฐํ
std::vector<int> v3(5, 10); // ํฌ๊ธฐ 5, 10์ผ๋ก ์ด๊ธฐํ
std::vector<int> v4 = {1, 2, 3, 4, 5}; // ์ด๊ธฐํ ๋ฆฌ์คํธ
// ์์ ์ถ๊ฐ
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
// ์ถ๋ ฅ
for (int num : v1) {
std::cout << num << " ";
}
std::cout << std::endl; // 10 20 30
return 0;
}
์์ ์ ๊ทผ¶
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {10, 20, 30, 40, 50};
// ์ธ๋ฑ์ค ์ ๊ทผ
std::cout << v[0] << std::endl; // 10
std::cout << v.at(2) << std::endl; // 30 (๋ฒ์ ๊ฒ์ฌ)
// ์ฒซ ๋ฒ์งธ/๋ง์ง๋ง
std::cout << v.front() << std::endl; // 10
std::cout << v.back() << std::endl; // 50
// ํฌ๊ธฐ
std::cout << "ํฌ๊ธฐ: " << v.size() << std::endl;
std::cout << "๋น์ด์์: " << v.empty() << std::endl;
return 0;
}
์ฝ์ ๊ณผ ์ญ์ ¶
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// ๋์ ์ถ๊ฐ/์ญ์
v.push_back(6); // {1, 2, 3, 4, 5, 6}
v.pop_back(); // {1, 2, 3, 4, 5}
// ์ค๊ฐ ์ฝ์
v.insert(v.begin() + 2, 100); // {1, 2, 100, 3, 4, 5}
// ์ค๊ฐ ์ญ์
v.erase(v.begin() + 2); // {1, 2, 3, 4, 5}
// ๋ฒ์ ์ญ์
v.erase(v.begin(), v.begin() + 2); // {3, 4, 5}
// ์ ์ฒด ์ญ์
v.clear();
return 0;
}
๋ฐ๋ณต์¶
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// ๋ฐ๋ณต์๋ก ์ํ
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// auto ์ฌ์ฉ (๊ถ์ฅ)
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// ์ญ์ ๋ฐ๋ณต์
for (auto it = v.rbegin(); it != v.rend(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl; // 5 4 3 2 1
return 0;
}
3. array¶
๊ณ ์ ํฌ๊ธฐ ๋ฐฐ์ด์ ๋๋ค.
#include <iostream>
#include <array>
int main() {
std::array<int, 5> arr = {1, 2, 3, 4, 5};
// ์ ๊ทผ
std::cout << arr[0] << std::endl;
std::cout << arr.at(2) << std::endl;
std::cout << arr.front() << std::endl;
std::cout << arr.back() << std::endl;
// ํฌ๊ธฐ
std::cout << "ํฌ๊ธฐ: " << arr.size() << std::endl;
// ์ํ
for (int num : arr) {
std::cout << num << " ";
}
std::cout << std::endl;
// ์ฑ์ฐ๊ธฐ
arr.fill(0);
return 0;
}
4. deque¶
์์ชฝ ๋์์ ์ฝ์ /์ญ์ ๊ฐ ๋น ๋ฅธ ์ปจํ ์ด๋์ ๋๋ค.
#include <iostream>
#include <deque>
int main() {
std::deque<int> dq;
// ์/๋ค์ ์ถ๊ฐ
dq.push_back(1);
dq.push_back(2);
dq.push_front(0);
dq.push_front(-1);
// {-1, 0, 1, 2}
for (int num : dq) {
std::cout << num << " ";
}
std::cout << std::endl;
// ์/๋ค์์ ์ญ์
dq.pop_front();
dq.pop_back();
// {0, 1}
for (int num : dq) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
5. list¶
์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ์ ๋๋ค.
#include <iostream>
#include <list>
int main() {
std::list<int> lst = {3, 1, 4, 1, 5};
// ์/๋ค์ ์ถ๊ฐ
lst.push_front(0);
lst.push_back(9);
// ์ ๋ ฌ (์์ฒด ๋ฉ์๋)
lst.sort();
for (int num : lst) {
std::cout << num << " ";
}
std::cout << std::endl; // 0 1 1 3 4 5 9
// ์ค๋ณต ์ ๊ฑฐ (์ฐ์๋ ๊ฒ๋ง)
lst.unique();
for (int num : lst) {
std::cout << num << " ";
}
std::cout << std::endl; // 0 1 3 4 5 9
// ์ฝ์
auto it = lst.begin();
std::advance(it, 2); // 2์นธ ์ด๋
lst.insert(it, 100); // ํด๋น ์์น์ ์ฝ์
return 0;
}
6. set¶
์ ๋ ฌ๋ ๊ณ ์ ์์์ ์งํฉ์ ๋๋ค.
#include <iostream>
#include <set>
int main() {
std::set<int> s;
// ์ฝ์
s.insert(30);
s.insert(10);
s.insert(20);
s.insert(10); // ์ค๋ณต, ๋ฌด์๋จ
// ์๋ ์ ๋ ฌ
for (int num : s) {
std::cout << num << " ";
}
std::cout << std::endl; // 10 20 30
// ํฌ๊ธฐ
std::cout << "ํฌ๊ธฐ: " << s.size() << std::endl; // 3
// ๊ฒ์
if (s.find(20) != s.end()) {
std::cout << "20 ์์" << std::endl;
}
// count (0 ๋๋ 1)
std::cout << "30์ ๊ฐ์: " << s.count(30) << std::endl;
// ์ญ์
s.erase(20);
return 0;
}
multiset¶
์ค๋ณต์ ํ์ฉํ๋ set์ ๋๋ค.
#include <iostream>
#include <set>
int main() {
std::multiset<int> ms;
ms.insert(10);
ms.insert(10);
ms.insert(20);
ms.insert(10);
for (int num : ms) {
std::cout << num << " ";
}
std::cout << std::endl; // 10 10 10 20
std::cout << "10์ ๊ฐ์: " << ms.count(10) << std::endl; // 3
return 0;
}
7. map¶
ํค-๊ฐ ์์ ์ ๋ ฌ๋ ์ปจํ ์ด๋์ ๋๋ค.
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<std::string, int> ages;
// ์ฝ์
ages["Alice"] = 25;
ages["Bob"] = 30;
ages.insert({"Charlie", 35});
ages.insert(std::make_pair("David", 40));
// ์ ๊ทผ
std::cout << "Alice: " << ages["Alice"] << std::endl;
// ์ํ (ํค ๊ธฐ์ค ์ ๋ ฌ๋จ)
for (const auto& pair : ages) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
// ๊ตฌ์กฐ์ ๋ฐ์ธ๋ฉ (C++17)
for (const auto& [name, age] : ages) {
std::cout << name << ": " << age << std::endl;
}
// ๊ฒ์
if (ages.find("Alice") != ages.end()) {
std::cout << "Alice ์์" << std::endl;
}
// ์ญ์
ages.erase("Bob");
return 0;
}
์ฃผ์: operator[]¶
std::map<std::string, int> m;
// ์๋ ํค ์ ๊ทผ โ ๊ธฐ๋ณธ๊ฐ(0)์ผ๋ก ์ฝ์
๋จ!
std::cout << m["unknown"] << std::endl; // 0 (๊ทธ๋ฆฌ๊ณ ์ฝ์
๋จ)
std::cout << m.size() << std::endl; // 1
// ์์ ํ ์ ๊ทผ
if (m.count("key") > 0) {
std::cout << m["key"] << std::endl;
}
// ๋๋ find ์ฌ์ฉ
auto it = m.find("key");
if (it != m.end()) {
std::cout << it->second << std::endl;
}
8. unordered_set / unordered_map¶
ํด์ ํ ์ด๋ธ ๊ธฐ๋ฐ์ผ๋ก ํ๊ท O(1) ์ ๊ทผ์ด ๊ฐ๋ฅํฉ๋๋ค.
unordered_set¶
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> us;
us.insert(30);
us.insert(10);
us.insert(20);
// ์์ ๋ณด์ฅ ์ ๋จ
for (int num : us) {
std::cout << num << " ";
}
std::cout << std::endl; // ์์ ๋ถํ์
// ๊ฒ์ (O(1) ํ๊ท )
if (us.count(20)) {
std::cout << "20 ์์" << std::endl;
}
return 0;
}
unordered_map¶
#include <iostream>
#include <unordered_map>
#include <string>
int main() {
std::unordered_map<std::string, int> umap;
umap["apple"] = 100;
umap["banana"] = 200;
umap["cherry"] = 300;
// ์ ๊ทผ (O(1) ํ๊ท )
std::cout << "apple: " << umap["apple"] << std::endl;
// ์ํ (์์ ๋ถํ์ )
for (const auto& [key, value] : umap) {
std::cout << key << ": " << value << std::endl;
}
return 0;
}
set vs unordered_set¶
| ํน์ง | set | unordered_set |
|---|---|---|
| ๋ด๋ถ ๊ตฌ์กฐ | ๋ ๋-๋ธ๋ ํธ๋ฆฌ | ํด์ ํ ์ด๋ธ |
| ์ ๋ ฌ | ์ ๋ ฌ๋จ | ์ ๋ ฌ ์ ๋จ |
| ์ฝ์ /๊ฒ์ | O(log n) | O(1) ํ๊ท |
| ์ํ ์์ | ์ ๋ ฌ ์์ | ๋ถํ์ |
9. stack๊ณผ queue¶
์ปจํ ์ด๋ ์ด๋ํฐ์ ๋๋ค.
stack (LIFO)¶
#include <iostream>
#include <stack>
int main() {
std::stack<int> s;
// push
s.push(10);
s.push(20);
s.push(30);
// pop (LIFO)
while (!s.empty()) {
std::cout << s.top() << " "; // ๋งจ ์ ์์
s.pop();
}
std::cout << std::endl; // 30 20 10
return 0;
}
queue (FIFO)¶
#include <iostream>
#include <queue>
int main() {
std::queue<int> q;
// push
q.push(10);
q.push(20);
q.push(30);
// pop (FIFO)
while (!q.empty()) {
std::cout << q.front() << " "; // ๋งจ ์ ์์
q.pop();
}
std::cout << std::endl; // 10 20 30
return 0;
}
priority_queue¶
#include <iostream>
#include <queue>
int main() {
// ๊ธฐ๋ณธ: ์ต๋ ํ (ํฐ ๊ฐ์ด ๋จผ์ )
std::priority_queue<int> pq;
pq.push(30);
pq.push(10);
pq.push(20);
while (!pq.empty()) {
std::cout << pq.top() << " ";
pq.pop();
}
std::cout << std::endl; // 30 20 10
// ์ต์ ํ
std::priority_queue<int, std::vector<int>, std::greater<int>> minPq;
minPq.push(30);
minPq.push(10);
minPq.push(20);
while (!minPq.empty()) {
std::cout << minPq.top() << " ";
minPq.pop();
}
std::cout << std::endl; // 10 20 30
return 0;
}
10. pair์ tuple¶
pair¶
#include <iostream>
#include <utility>
int main() {
// ์์ฑ
std::pair<std::string, int> p1("Alice", 25);
auto p2 = std::make_pair("Bob", 30);
// ์ ๊ทผ
std::cout << p1.first << ": " << p1.second << std::endl;
// ๋น๊ต
if (p1 < p2) { // first ๋จผ์ , ๊ฐ์ผ๋ฉด second
std::cout << p1.first << " < " << p2.first << std::endl;
}
return 0;
}
tuple¶
#include <iostream>
#include <tuple>
#include <string>
int main() {
// ์์ฑ
std::tuple<std::string, int, double> t("Alice", 25, 165.5);
// ์ ๊ทผ
std::cout << std::get<0>(t) << std::endl; // Alice
std::cout << std::get<1>(t) << std::endl; // 25
std::cout << std::get<2>(t) << std::endl; // 165.5
// ๊ตฌ์กฐ์ ๋ฐ์ธ๋ฉ (C++17)
auto [name, age, height] = t;
std::cout << name << ", " << age << ", " << height << std::endl;
return 0;
}
11. ์ปจํ ์ด๋ ์ ํ ๊ฐ์ด๋¶
| ์๊ตฌ์ฌํญ | ๊ถ์ฅ ์ปจํ ์ด๋ |
|---|---|
| ์์ฐจ ์ ๊ทผ + ๋ ์ฝ์ /์ญ์ | vector |
| ์์ชฝ ๋ ์ฝ์ /์ญ์ | deque |
| ์ค๊ฐ ์ฝ์ /์ญ์ ๋น๋ฒ | list |
| ๊ณ ์ ์์ + ์ ๋ ฌ | set |
| ๊ณ ์ ์์ + ๋น ๋ฅธ ๊ฒ์ | unordered_set |
| ํค-๊ฐ + ์ ๋ ฌ | map |
| ํค-๊ฐ + ๋น ๋ฅธ ๊ฒ์ | unordered_map |
| LIFO | stack |
| FIFO | queue |
| ์ฐ์ ์์ | priority_queue |
12. ์์ฝ¶
| ์ปจํ ์ด๋ | ํน์ง |
|---|---|
vector |
๋์ ๋ฐฐ์ด, ๋ O(1) |
array |
๊ณ ์ ๋ฐฐ์ด |
deque |
์์ชฝ ๋ O(1) |
list |
์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ |
set |
์ ๋ ฌ + ๊ณ ์ |
map |
ํค-๊ฐ + ์ ๋ ฌ |
unordered_set |
ํด์ + ๊ณ ์ |
unordered_map |
ํด์ + ํค-๊ฐ |
stack |
LIFO |
queue |
FIFO |
priority_queue |
ํ |
๋ค์ ๋จ๊ณ¶
11_STL_์๊ณ ๋ฆฌ์ฆ๊ณผ_๋ฐ๋ณต์.md์์ STL ์๊ณ ๋ฆฌ์ฆ์ ๋ฐฐ์๋ด ์๋ค!