Language/C++

15.STL Containers

아무키 2023. 12. 25. 12:00
반응형
list<int> l{1,2,3};

l.front() = 1;
l.back() = 3;

// 1 - > 2 -> 3 포인터를 갖고 있다.

컨테이너의 종류

Sequence 컨테이너

→ 삽입 순서를 유지하는 컨테이너

→ array, vector, deque, list, forward_list

Associative 컨테이너

→ 순서가 없거나, 미리 정해진 규칙에 따라 저장하는 컨테이너

→ set, multi set, map, multi map

컨테이너 어뎁터

→ 다른 컨테이너들의 변형 응용

→ stack, queue, priority queue

 

Sequence Container - Array

std::array (C++11)

#include <array>

고정 크기 배열

기존의 정적 배열(raw array)(ex : int arr[5] = {1,2,3,4,5})와 거의 유사함

요소에 대한 직접 접근(constant time)

STL이므로, iterator와 algorithm을 사용 가능

특별한 이유가 없으면 raw array 대신 STL array를 사용

 

array의 초기화 및 대입

array<int , 5> arr1 { {1,2,3,4,5} }; // C++11 style
array<int, 5> arr1 {1,2,3,4,5}; //C++14 style

array<string, 3> names{
	"Ha",
	"Kim",
	"Lee"
};

arr1 = {2, 4, 6, 8, 10};

 

array의 주요 함수들(1)

array<int, 5> {1,2,3,4,5}; //C++14 style

cout << arr.size(); // 5 (배열의 현재 크기 반환)
cout << arr.at(0); // 1 (배열의 0번째 인덱스 값을 반환)
cout << arr[1]; // 2 (배열의 1번째 인덱스 값을 반환)

cout << arr.front(); // 1 (배열의 0번째 인덱스 값을 반환)
cout << arr.back(); // 5 (배열의 마지막 인덱스 값을 반환

 

array의 주요 함수들(2)

array<int, 5> arr{1,2,3,4,5};
array<int, 5> arr1{10,20,30,40,50};

cout << arr.empty(); // 0 (false) (배열의 요소가 있다면 false)
cout << arr.max_size(); // 5 (배열의 최대 크기 반환)

cout << arr.fill(10); // 배열의 모든 요소를 10으로 채움
arr.swap(arr1); // 두 배열을 swap
int *data = arr.data(); // 배열의 주소를 반환

 

Sequence Container - Vector

 

std::vector

#include <vector>

가변 크기 배열

요소에 대한 직접 접근(constant time)

요소의 끝 위치 삽입(push_back) 및 제거(pop_back)(constant time)

임의 위치에 요소의 삽입 및 제거(linear time)

반복자가 유효하지 않을 수 있다.

 

front / back

vector<int> v{1,2,3};

v.front() = 1;
v.end() = 3;

v.push_back(4); // v = {1, 2, 3, 4}
#include <iostream>
#include <vector>

int main(){
	std::vector<int> v{1,2,3,4,5};

	std::cout << v.size() << std::endl; // 5
	std::cout << v.capacity() << std::endl; // 5

	std::cout << v[0]; // 1
	std::cout << v[1]; // 2
	std::cout << v.at(3); // 4

	std::cout << v[-1]; //runtime error
	std::cout << v.at(-1); //exception error
	//예외처리를 함으로써 at이 더 안전할 수 있다.

	std::cout << v.front(); // 1
	std::cout << v.back(); // 5

 

vector의 주요 함수들

Person p1{"Ha", 20};
vector<Person> v;

v.push_back(p1); // add p1 to the back, copy
v.pop_back(); //remove p1 from the back

v.push_back(Person("Lee", 20});

v.emplace_back("Lee", 20);
//same as above statement, but more efficient
//Check how many copy ctor called in push_back

 

vector의 주요 함수들 2

vector<int> v1{1,2,3,4,5};
vector<int> v2{10,20,30,40,50};

cout << v1.empty(); //0 (false)
v1.swap(v2); // swap 2 vector

sort(v1.begin(), v1.end());

auto it = find(v1.begin(), v1.end(), 3); //값 3을 찾음
v1.insert(it, 10); // 1,2, 10, 3, 4, 5 //it 앞에 값 10을 삽입

it = find(v1.begin(), v1.end(), 4);

v1.insert(it, v2.begin(), v2.end());
//1 2 10 3 10 20 30 40 50 4 5

 

Sequence Container - List & Forward List

 

Sequence 컨테이너

연속된 메모리 공간에 저장되지 않음

요소에 대한 직접 접근 불가(.at() 또는 [ ]로 접근 불가)

요소의 위치가 결정되면, 삽입과 삭제가 매우 효율적

 

std::list(C++11)

.#include <list>

 

가변 크기

양방향 연결 리스트

요소에 대한 직접 접근 불가

임의 위치에 빠른 삽입과 삭제(constant time)

특정 요소를 검색(find)하는 데는 linear time

반복자 유효성 보장 안됨

 

list

list<int> l{1,2,3};

l.front() = 1;
l.back() = 3;

// 1 - > 2 -> 3 포인터를 갖고 있다.

 

 

list의 초기화 및 대입

list<int> l1{1,2,3,4,5};
list<int> l2{10, 100};

list<string> names{"kim", "lee", "park"};

l1 = {2,4,5,8,10};

 

list의 주요 함수들

list<int> l1{1,2,3,4,5};

cout << l1.size(); // 5
cout << l1.max_size(); // very large number

cout << l1.front(); // 1
cout << l1.back(); // 5

 

list의 주요 함수들 2

Person p1{"Kim", 20};
list<Person> l;

l.push_back(p1); // add p1 to the back
l.pop_back(); // remove p1 from back

l.push_front(Person{"lee", 21});
l.pop_front(); //remove front element

l.emplace_front("Choo", 25);

 

list의 주요 함수들 3

list <int> l1{1,2,3,4,5};

auto it = find(l1.begin(), l1.end(), 3);

l1.insert(it, 10); // 1 2 10 3 4 5
l1.erase(it); // 1 2 10 4 5 <- it 유효성 사라짐
l1.resize(2); // 1 2
l1.resize(5); // 1 2 0 0 0

cout << *it; // 3
it++;
cout << *it; // 4
it--;
cout << *it; // 3

 

 

std::forward_list(C++11)

#include <forward_list>

 

가변크기

단방향 연결 리스트(메모리 절약)

요소에 대한 직접 접근 불가

임의 위치에 빠른 삽입과 삭제(constant time)

특정 요소를 검색(find)하는 데는 linear time

반복자 유효성 보장 안됨

reverse iterator 사용 불가

forawrd_list<int> l{1,2,3};

l.front() // 1

 

Associative Container - Set

Associative 컨테이너

Key를 사용한 빠른 데이터 검색이 가능

주로 Balanced binary tree 또는 hashset으로 구현됨

대부분의 연산이 빠르게 이루어짐

 

Set

set

Unordered_set

Multiset

Unordered_multiset

 

std::set

#include <set>

 

집합과 유사(중복된 요소 없음)

key에 따라 정렬

요소에 대한 직접 접근 불가

반복자가 유효하지 않을 수 있다.

 

set의 초기화 및 대입

set<int> s{1,2,3,4,5};
set<string> names{"kim", "ha", "oh"};

s = {2,4,6,8,10};

 

set의 주요 함수들

set<int> s{4,1,1,3,2,5}; // 1 2 3 4 5

cout << s.size(); // 5
cout << s.max_sizel // vary large number

//no front or back

s.insert(7) // 1 3 4 5 7

 

set의 주요 함수들 2

Person p1{"kim", 20};
Person p2{"lee", 21};

set<Person> names;

names.insert(p1); // add p1 to the set
auto result = names.insert(p2); // add p2 to the set

 

정렬을 위해 operator< 오버로딩 필요

insert의 결과로 pair<iterator, bool>반환

iterator는 삽입된 위치, 또는 이미 존재하는 요소를 가리키는 반복자 반환

Bool은 성공 또는 실패 결과 반환

 

set의 주요 함수들 3

set<int> s{1,2,3,4,5};

s.erase(3); // 1 2 4 5

auto it = s.find(5);
//algorithm의 find가 아닌 set의 멤버 변수인 find

if(it != s.end())
		s.erase(it); // 1 2 4

 

set의 주요 함수들 4

set<int> s{1,2,3,4,5};

int n = s.count(1); // 0 or 1
s.clear(); // remove all elements
s.epmty(); // true or false

 

multiset

Key로 정렬

요소의 중복 허용

 

unordered_set

요소의 중복 불가

요소가 정렬되지 않음

요소의 수정 불가

 

unordered_multiset

요소가 정렬되지 않음

요소의 중복 허용

 

Associative Container - Map

Associative 컨테이너

Key를 사용한 빠른 데이터 검색이 가능

주로 Balanced binary tree또는 hashset으로 구현됨

대부분의 연산이 빠르게 이루어짐

 

Map

Map

Unordered_map

Multimap

Unordered_multimap

 

std::map

#include<map>

 

Dictionary(사전)과 유사

요소가 key-value 쌍으로 저장됨

Key 값에 따라 정렬

Key는 유일한 값으로 중복 불가

Key를 통한 직접 접근 가능

반복자가 유효하지 않을 수 있음

 

map의 초기화 및 대입

map<string, int> m1{
	{"kim", 20}, {"lee", 21}, {"kim", 25}
};
//중복되는 뒤에 kim 25는 없어짐
map<string, string> m2{
	{"kim", "student"}, {"Lee", "pro"};

 

map의 주요 함수들 1

map<string, string> m{
	{"kim", "stu"}, {"lee", "pro"}
};

pair<string, string> p1{"park", "assi"};
m.insert(p1);
m.insert(make_pair("Choo", "emp"));

 

map의 주요 함수들 2

map<string, string> m{
	{"kim", "stu"}, {"lee", "pro"}
};

m["park"] = "assi"; // insert
m["kim"] = "emp"; // update value
m.at("park") = "stu"; //update value

int n =m.count("kim"); // 0 or 1
m.clear(); //remove all elements
m.empty(); //true or false

 

multimap

#include <map>에 포함

중복된 요소들 허용

 

unordered map

#include <unordered_map>

요소가 정렬되지 않음

 

unordered multimap

#include <unordered_map>에 포함

요소가 정렬되지 않음

중복된 요소를 허용

반응형