순차열 컨테이너는 데이터 관리에 유용하지만, 대다수 프로그램에서 순차열 컨테이너가 편리한 데이터 엑세스 도구는 아니다. 이름과 주소를 관리할때도 순차열 컨테이너는 적합하지 않을수 있음.
연관 컨테이너는 객체를 객체와 연관된 키 값으로 위치를 정한다. 키값은 기본타입일수도 있고, 클래스 객체일수도 있다.
연관 컨테이너
map <K, T>
키/객체 쌍을 캡슐화한pair<const K, T>
타입을 원소로 지정한다. 키는 유일해야하며, 키 값만 다르다면 중복 객체도 저장가능multimap<K, T>
map<K, T>
와 같지만, 중복키를 허용한다. 원소들의 순서는 키를 비교해서 결정.unordered_map<K, T>
pair <const K, T>
객체를 키값으로 직접 정렬하지 않는다. 원소는 키 값으로 생성된 해시 값으로 사용해 위치가 정해진다. 중복 키는 허용되지 않는다.unorederd_multimap<K, T>
중복키를 허용한unordered_map<K, T>
map 컨테이너
map 컨테이너는 원소들을 Key을 기준으로 균형 이진 트리로 저장한다. 임의의 원소를 가져오는 시간은
O(log N)
이고, 순차열에서 원소를 가져오는시간은O(N)
이다
- 정렬해야 한다.
- 많은 자료를 저장하고, 검색이 빨라야 한다
- 빈번하게 삽입, 삭제하지 않는다
map 컨테이너 생성
1 | map<string, size_t> people; // 이름을 키, 나이를 값으로 저장하는 맵 컨테이너 |
map 컨테이너 원소 삽입 및 내부 생성
1 | map<string, size_t> people; |
원소 접근
map 컨테이너는 역방향 반복자로 접근할수 있다. 키가 없다면 out_of_range Exception이 발생된다.
1 | map<Name, size_t> people; |
pair, tuple 객체 사용하기
tuple 객체는 pair 템플릿을 일반화 한것으로 타입이 다른 객체를 몇개라도 캡슐화한 tuple 템플릿 인스턴스를 정의할수 있다.
1 | // C++ 11 매커니즘 사용한 pair 생성 |
우측값 참조란 기능이 추가되어 메모리의 “복사”가 아니라 “이동”이 가능해 졌다는것!!!
Unordered_map 컨테이너
해쉬테이블
헤쉬테이블은 Key, Value로 갖는 자료구조로, 주어진 키로 적합한 값을 찾는 자료구조다. 주어진 키를 해쉬값으로 변환하고 해쉬값을 인덱스로 바꾸어 원하는 값 (버켓)을 찾아낸다.
검색성능 : 최악 O(N), 평균 O(1)
STL 해싱
functional에
hash<K>
템플릿의 특수화가 정의되어 있음.
hash<K>
인스턴스의operator()()
맴버는 타입 K만 인수 받아서 해시 값을 size_t 타입으로 변환한다.
- Exception을 던지면 안된다.
- 키가 같으면 해시값도 같아야된다.
- 다른키일때 충돌할 가능성이 매우 적어야된다.
1 | hash<int> hash_int; |
이제 제대로 사용해보기
지원하는 해시함수가 반드시 필요한데, 직접 정의한 클래스 타입의 객체를 키로 사용한다면, 해당 타입의 객체에 맞는 해시함수를 만들어야 된다.
STL에서
hash<T>
특수화로 지원되는 타입의 객체가 키라면 컨테이너는 키에 대한 해시 값을 생성하는데 이 특수화를 이용할수 있다.
많은 자료를 저장하고, 검색 속도가 빨라야 한다.
너무 빈번하게 자료를 삽입, 삭제 하지 않는다.
버컷은 해시테이블에 저장되는 항목들을 말한다.
원소 저장방식에 영향을 주는 요소
- 컨테이너의 버킷의 갯수, 버킷 갯수에 기본값이 있겟지만, 초기 갯수 지정할수 있음.
- 로드 펙터(load factor) 버킷당 저장된 원소의 평균 갯수를 말한다. 컨테이너의 원소 개수를 버킷 개수로 나눈값
- 로드펙터의 최대값. 기본값은 1.0이지만 로드펙터의 상한값을 지정한다. 최댓값에 도달한다면, 더 많은 버킷을 할당하기 위해 메모리 공간을 할ㄷ당한다. 보통 이과정은 컨테이너에 있는 원소들에 대해 재해싱하게 된다.
unordered_map은 상등관계를 위해 키를 비교할수 있어야 된다. 컨테이너에 이미 같은 키가 있을때 둘 이상의 원소가 담긴 버킷에서 특정 원소를 식별하고 결정할수 있으려면 키 비교가 반드시 필요
functional 헤더의
equal_to<K>
을 사용할것. 키에 == 연산자 적용한다(상등관계 ==로 값을 찾는다.). map 컨테이너 같은 경우 동등관계로 위치가 같은지 판단한다. (<, > 로 값을 찾는다.)
컨테이너 생성 및 관리
키 타입 K를
hash<K>
인스턴스로 해시할수 있고, == 연산자를 이용해 키를 비교할수만 있다면 해당 컨테이너는 사용가능.
1 | unordered_map<string, size_t> people { {"Jan", 44}, {"Jim", 33}, {"Joe", 99}}; |
원소 삽입, 삭제, 접근과 버킷 접근
1 | unordered_map<string, size_t> people; |