[C++ 표준] STL 컨테이너 소개
카테고리: STL
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
컨테이너 소개
- STL 의 구성 요소 중 하나
- 데이터를 저장하는 객체들이다.
- 컨테이너의 구성 요소
- sequence containers
- associative containers
- container adapters
1️⃣ Sequence Containers
정렬되지 않은 연결리스트/배열
vector
#include <vector>
- 동적 배열이다.
- 원소가 되는 객체를 삽입하거나 삭제시 자동으로 자신의 크기를 조정
push_back
,end
,begin
,back
,front
,size
등등 다양한 함수 有- 보통 끝에 삽입한다. 👉
push_back
- 벡터는
push_front
는 없다.
- 벡터는
#include <vector>
#include <iostream>
using namespace std;
int main()
{
{
std::vector<int> vec;
for (int i = 0; i < 10; ++i)
vec.push_back(i);
for (auto& itr : vec)
cout << itr << " ";
cout << "\n";
}
}
deque
#include <deque>
- 동적 배열이다.
- 시작 & 끝에서 삽입과 삭제를 수행하는 벡터.
push_front
,push_back
- vector와 달리
push_front
가 있다.
#include <deque>
#include <iostream>
using namespace std;
int main()
{
{
std::deque<int> deq; // #include <deque>
for (int i = 0; i < 10; ++i)
{
deq.push_back(i);
deq.push_front(i);
}
for (auto& itr : deq)
cout << itr << " ";
cout << "\n";
}
}
💎출력💎
9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
list
#include <list>
- 이중 연결 리스트 (양방향)
- 배열과 달리 요소들이 서로 근접한 메모리에 연속적으로 저장되지 않음.
- 검색과 접근이 느리지만 일단 검색이 되면 빠른 삽입과 제거 시간을 가진다.
slist
#include <slist>
- 이중 연결 리스트 (단방향)
- 배열과 달리 요소들이 서로 근접한 메모리에 연속적으로 저장되지 않음.
- 검색과 접근이 느리지만 일단 검색이 되면 빠른 삽입과 제거 시간을 가진다.
2️⃣ Associative Containers
정렬 된 컨테이너
set
#include <set>
insert
함수로 삽입함- 자동으로 정렬 된다.
- 원소가 중복이 되지 않는다.
- 삽입하려는 아이템이 이미 set 안에 있어 중복이 된다면 삽입되지 않고 무시한다.
#include <set>
#include <iostream>
using namespace std;
int main()
{
{
std::set<string> strSet;
strSet.insert("Hello");
strSet.insert("World");
strSet.insert("Hello"); // 삽입 안되고 무시된다. 이미 중복된 원소가 있어서!
cout << strSet.size() << "\n";
for (auto& itr : strSet)
cout << itr << " ";
cout << "\n";
}
}
💎출력💎
2
Hello World
multiset
#include <multiset>
insert
함수로 삽입함- 자동으로 정렬 된다.
- 원소 중복이 허용된다.
#include <multiset>
#include <iostream>
using namespace std;
int main()
{
{
std::multiset<string> strSet;
strSet.insert("Hello");
strSet.insert("World");
strSet.insert("Hello");
cout << strSet.size() << "\n";
for (auto& itr : strSet)
cout << itr << " ";
cout << "\n";
}
}
💎출력💎
3
Hello Hello World
map
#include <map>
- Key를 기준으로 자동으로 정렬 된다.
- Key와 Value가 존재한며 둘이 대응된다.
- Key로 Value에 접근한다.
- Key는 중복이 되지 않는다.
- 삽입하려는 Key가 이미 map 안에 있어 중복이 된다면 삽입되지 않고 무시한다.
- Key와 Value를
pair
로 삽입하거나[key] = value
형식으로 삽입해야 한다.first
👉 Keysecond
👉 Value
#include <map>
#include <iostream>
using namespace std;
int main()
{
{
std::map<char, int> userMap;
userMap['a'] = 10; // userMap['a'] = 10; (o) / userMap['a'](10) (x)
userMap['b'] = 20;;
userMap.insert(make_pair('c', 50));
cout << userMap['a'] << "\n";
userMap.insert(make_pair('a', 100)); // 'a' Key는 이미 있으므로 무시된다.
cout << userMap['a'] << "\n";
cout << userMap.size() << "\n";
for (auto& itr : userMap)
cout << "Key = " << itr.first << " " << "Value = " << itr.second << "\n";
cout << "\n";
}
}
💎출력💎
10
10
3
Key = a Value = 10
Key = b Value = 20
Key = c Value = 50
multimap
#include <multimap>
- Key를 기준으로 자동으로 정렬 된다.
- Key와 Value가 존재한며 둘이 대응된다.
- Key로 Value에 접근한다.
- Key는 중복 가능하다.
- 따라서
count
라는 함수가 따로 존재한다.- 해당 키를 가진 value가 몇개인지 리턴.
- 중복이 허용되므로 하나의 Key는 여러개의 value를 가질 수 있다.
- 해당 키를 가진 value가 몇개인지 리턴.
- 따라서
- Key와 Value를
pair
로 삽입하거나[key] = value
형식으로 삽입해야 한다.first
👉 Keysecond
👉 Value
#include <multimap>
#include <iostream>
using namespace std;
int main()
{
{
std::multimap<char, int> userMap;
userMap.insert(std::pair<char, int>('a', 10)); // C++ 17 이전 문법
userMap.insert(std::pair('b', 20)); // C++ 17 이후 문법
userMap.insert(std::pair('c', 50));
userMap.insert(std::pair('a', 100)); // 중복 허용.
userMap.insert(std::pair('a', 200)); // 중복 허용. 'a' Key는 10, 100, 200 이렇게 총 3개의 value를 가지게 된다.
cout << userMap.count('a') << endl; // 출력
for (auto & itr : userMap)
cout << "Key = " << itr.first << " " << "Value = " << itr.second << "\n";
cout << "\n";
}
}
💎출력💎
3
Key = a Value = 10
Key = a Value = 100
Key = a Value = 200
Key = b Value = 20
Key = c Value = 50
unordered_set
#include <unordred_set>
- 정렬되지 않는다.
- 해시 테이블에 저장되며 해시 함수로 접근하게 된다.
- 원소가 중복이 되지 않는다.
unordered_map
#include <unordred_set>
- 정렬되지 않는다.
- 해시 테이블에 저장되며 해시 함수로 접근하게 된다.
- Key와 Value가 존재한며 둘이 대응된다.
- Key로 Value에 접근한다.
- Key는 중복이 되지 않는다.
- 마찬가지로
pair
로 삽입된다.
bitset
#include <bitset>
- 비트를 저장하는 컨테이너
- 반복자가 쓰이지 않는다. 임의 접근 제공.
3️⃣ Container Adapter
Container 위에서 돌아가는 자료 구조다. 보통 디폴트로 vector로 구현 됨.
- 스택
- 큐
- 우선순위 큐
Stack
#include <stack>
- 층층이 쌓아 올리기
- 가장 최근에 삽입한 것이 가장 먼저 삭제 된다.
- 삽입
push
: copy 해서 삽입emplace
: 새로운 객체를 만들어서 삽입
top
- 스택에서 가장 위에 있는 것
- 가장 최근에 삽입된 것
pop
- 가장 위에 있는 것을 삭제
- 가장 최근에 삽입된 것을 삭제
#include <stack>
#include <iostream>
using namespace std;
int main()
{
{
std::stack<int> userStack;
userStack.push(1);
userStack.emplace(2);
userStack.emplace(3);
cout << userStack.top() << "\n";
userStack.pop();
cout << userStack.top() << "\n";
}
}
💎출력💎
3
2
queue
#include <queue>
- 줄 서기
- 가장 최근에 삽입된 것이 가장 늦게 삭제 된다.
- 맨 앞에 있는 것이 먼저 삭제 된다.
front()
- 맨 앞에 있는 것 리턴
- 삽입 된 지 가장 오래 된 것 리턴
back()
- 맨 뒤에 있는 것 리턴
- 가장 최근에 삽입 한 것 리턴
pop ()
- 맨 앞에 있는 것 리턴 후 삭제
#include <queue>
#include <iostream>
using namespace std;
int main()
{
{
std::queue<int> userQueue;
userQueue.push(1);
userQueue.emplace(2);
userQueue.push(3);
cout << userQueue.front() << userQueue.back() << "\n";
userQueue.pop();
cout << userQueue.front() << userQueue.back() << "\n";
}
}
💎출력💎
3
2
priority_queue
#include <queue>
- queue 처럼 단순히 들어온 순서대로가 아닌 높은 우선순위 요소일 수록 먼저 pop 됨
- 디폴트로는 최대값이 pop 됨
- 따라서 우선 순위대로 자동 정렬 을 한다.
- 우선순위를 내가 원하는 대로 지정하고 싶다면 크기를 비교하는 연산자 오버로딩을 하면 됨.
#include <queue>
#include <iostream>
using namespace std;
int main()
{
{
std::priority_queue<int> userPriQueue;
for (const int n : {1, 8, 5, 6, 3, 4, 0, 9, 7, 2})
userPriQueue.push(n); // 자동 정렬이 된다. 우선순위 큐
for (int i = 0; i < 10; ++i)
{
cout << userPriQueue.top() << " ";
userPriQueue.pop();
}
}
}
💎출력💎
9 8 7 6 5 4 3 2 1 0
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기