배움 저장소
[홍정모의 따라하며 배우는 C++] 16. 표준 템플릿 라이브러리 본문
16.1 표준 템플릿 라이브러리, 컨테이너 소개
Standard Template Libraries and Containers
- STL은 Standard Template Library의 줄임말이다. Algorithms, Containers, Iterators, Functions가 있다.
- STL과 Standard Library를 구분하지 않고 사용하기도 한다.
- Standard Library를 특별히 공부하기 보다 필요할 때 필요한 내용을 찾아서 사용함이 현명하다.
ㄴ https://en.cppreference.com/w/cpp/header
Container
여러 자료형을 쉽게 다룰 수 있도록 만든 클래스로 여러 기능이 멤버함수로 구현되어있다.
https://en.cppreference.com/w/cpp/container
Containers library - cppreference.com
The Containers library is a generic collection of class templates and algorithms that allow programmers to easily implement common data structures like queues, lists and stacks. There are three classes of containers -- sequence containers, associative cont
en.cppreference.com
container는 3가지 종류로 나뉜다. sequeunce container, associative container, container adapter.
(1) Sequence Container
ㄴ vector : 메모리 맨 뒤에 데이터를 추가할 수 있다.
ㄴ deque : 메모리 맨 앞/뒤 상관없이 데이터를 추가할 수 있다.
deque<int> deq; // #include <deque>
for (unsigned i = 0; i < 10; ++i) {
deq.push_front(i);
deq.push_back(i);
}
(2) Associatvie Container
ㄴ set : set은 중복되는 값은 무시한다.
set<int> test_set; // include <set>
test_set.insert(1);
test_set.insert(1);
test_set.insert(2);
for(auto& e:test_set)
cout << e << " ";
위 코드에서 1을 두 번 삽입하였으나 한 번만 저장됨을 알 수 있다.
>> 1 2
ㄴ multiset : set과 달리 중복되는 값도 넣을 수 있다
multiset<int> test_set; // include <set>
test_set.insert(1);
test_set.insert(2);
test_set.insert(1);
for(auto& e:test_set)
cout << e << " ";
아래 출력값을 보자. 순서가 바뀌어있다. 1 2 1이 출력될 거 같지만 중복되는 값은 함께 묶어준다.
>> 1 1 2
ㄴmap : key와 value를 대응하여 사용한다. 연산자 [ ]가 오버로딩되어 있다.
등록되지 않은 key에 value를 할당하면 새로운 공간을 만든다. 등록된 key에 value를 할당하면 다른 값을 삽입한다.
map<char, int> test_map;
test_map['c'] = 3;
test_map['b'] = 2;
test_map['a'] = 1;
cout << test_map['a'] << endl;
test_map['a'] = 10;
cout << test_map['a'] << endl;
for(auto& e:test_map)
cout << "k:" << e.first << " v:" << e.second << endl;
이 때 출력값이 정렬되어있음을 확인하자. 위 코드에서 'c' - 'b' - 'a' 순서로 key를 사용하였다. 자료구조 때 배운다.
>> 1
>> 10
>> k:a v:10
>> k:b v:2
>> k:c v:3
ㄴmultimap : multimap은 동일한 key에 여러 값을 담을 수 있다.
- 아래는 'c'-'b'-'a'순서로 값을 삽입하였지만 정렬되어 출력된다.
multimap<char, int> test_multimap; // include <map>
test_multimap.insert(std::pair('c', 3)); // Before C++ 14,
test_multimap.insert(std::pair('b', 2)); // you have to use pair
test_multimap.insert(std::pair('a', 1)); // like this
test_multimap.insert(std::pair('a', 10)); // pair<char,int>('a',1)
cout << test_multimap.count('a') << endl; // how many key 'a'
for(auto& e:test_multimap)
cout << "k:" << e.first << " v:" << e.second << endl;
count( )는 해당 key가 몇 개의 값을 가지고있는지 출력한다.
>> 2
>> k:a v:1
>> k:a v:10
>> k:b v:2
>> k:c v:3
(3) container adapters
ㄴstack : FIFO구조이다. FIFO(First In Last Out으로 먼저 들어온 값이 나중에 나간다)
멤버함수 push vs emplace
- push는 인자로 들어온 인스턴스사용한다. 단일 인스턴스만 사용가능하다.
- emplace는 해당 인스턴스를 사용하지 않고 새로운 생성자를 호출한다. emplace는 여러 인스턴스를 사용할 수 있다.
stack<int> stk; // #include <stack>
stk.push(1); // 'push' add a copy
stk.emplace(2); // 'emplace' construct new obj
cout << stk.top() << endl;
stk.pop();
cout << stk.top() << endl;
ㄴqueue : LIFO를 사용한다. LIFO(Last in First Out으로 나중에 들어온 값이 먼저 나간다.)
std::queue<int> que; // #include<queue>
que.push(1);
que.push(2);
que.push(3);
cout << que.front() << " " << que.back() << endl;
que.pop();
cout << que.front() << " " << que.back() << endl;
>> 1 3
>> 2 3
ㄴpriority queue : queue에 정렬기능이 더해져있다.
클래스를 만들어 priority queue에서 사용하려면 비교 연산자를 오버로딩해야 한다.
priority_queue<int> p_que; // #include <queue>
for(const int i: {7, 2, 4, 8, 6, 3, 9, 1, 5})
p_que.push(i);
while(p_que.size()) {
int size = p_que.size();
cout << p_que.top() << " ";
p_que.pop();
}
>> 9 8 7 6 5 4 3 2 1
16.2 STL 반복자 소개
Iterators
Iterator(반복자)를 활용한 예제이다
vector<int> container;
for (unsigned i = 0; i < 10; ++i)
container.push_back(i);
//vector<int>::iterator itr;
vector<int>::const_iterator itr;
/* Iteraotr with while-loop */
itr = container.begin();
while (itr != container.end()) {
cout << *itr << " ";
++itr;
}
cout << endl;
/* Iteraotr with for-loop */
for (auto iter = container.begin(); iter != container.end(); ++iter)
cout << *iter << " ";
cout << endl;
container를 변경하여도 위 iterator를 사용할 수 있어 유용하다. 아래 예제 모두 위에있는 코드로 실행할 수 있다.
list<int> container;
for (unsigned i = 0; i < 10; ++i)
container.push_back(i);
list<int>::const_iterator itr;
array<int,10> container;
for (unsigned i = 0; i < 10; ++i)
container[i] = i;
array<int, 10>::const_iterator itr;
set<int> container;
for (unsigned i = 0; i < 10; ++i)
container.insert(i);
set<int>::const_iterator itr;
map은 출력할 때 first와 second가 나뉘어져 있으므로 위의 실행코드를 조금 고쳐주어야 한다.
map<char,int> container;
for (unsigned i = 0; i < 10; ++i)
container[char('a'+i)] = i;
map<char,int>::const_iterator itr;
16.3 STL 알고리즘 소개
STL container를 유용하게 사용할 수 있도록 도와주는 STL 알고리즘을 알아보자.
https://en.cppreference.com/w/cpp/algorithm
Algorithms library - cppreference.com
The algorithms library defines functions for a variety of purposes (e.g. searching, sorting, counting, manipulating) that operate on ranges of elements. Note that a range is defined as [first, last) where last refers to the element past the last element to
en.cppreference.com
<algorithm>에서 자주 사용하는 함수
vector<int> container;
for(int i=0; i<10; ++i)
container.push_back(i);
/* get MIN */
auto itr = min_element(container.begin(), container.end());
cout << *itr << endl;
/* get MAX */
itr = max_element(container.begin(), container.end());
cout << *itr << endl;
/* find 4, insert -1 infrot of it */
itr = find(container.begin(), container.end(), 4);
container.insert(itr, -1);
for(auto&e : container) cout << e << " ";
cout << endl;
/* Sort */
sort(container.begin(), container.end());
for (auto& e : container) cout << e << " ";
cout << endl;
/* Sort Reversed order */
reverse(container.begin(), container.end());
for (auto& e : container) cout << e << " ";
cout << endl;
이 때 list는 sort함수를 호출하면 에러가 발생한다. 내부에 구현된 멤버함수 sort를 사용해주자. 자료구조에서 list와 vector의 차이를 알게되면 왜 이렇게 되는지 알게된다. STL container에 따라 사용법이 조금씩 달라짐을 확인하자.
list<int> li;
// sort(li.begin(), li.end()); // Error!
li.sort();
직접 구현한 클래스에서 STL 알고리즘을 사용하려면 비교연산자 오버로딩을 해주자.
'Programming Language > C++' 카테고리의 다른 글
[홍정모의 따라하며 배우는 C++] 18. 입력과 출력 (0) | 2022.01.05 |
---|---|
[홍정모의 따라하며 배우는 C++] 17. std::string 문자열 클래스 (0) | 2022.01.02 |
[홍정모의 따라하며 배우는 C++] 15. 의미론적 이동과 스마트 포인터 (0) | 2022.01.01 |
[따라하며 배우는 C++] 14. 예외처리 (0) | 2021.12.30 |
[홍정모의 따라하며 배우는 C++] 13. 템플릿 (0) | 2021.12.30 |