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 ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ฐฐ์›Œ๋ด…์‹œ๋‹ค!

to navigate between lessons