unordered_map (=hash_map), unordered_set (=hash_set)
연관 컨테이너이다.
괄호안의 이름 그대로 해시를 이용한다. 다만 hash_map과 hash_set 사용 시 더이상 사용되지 않으며 곧 삭제될테니 unordered_map, unordered_set을 사용하라는 컴파일러의 에러메시지가 출력된다.
hash_ 는 비표준 컨테이너, unordered_ 는 표준 컨테이너이다.. 기능은 거의 유사하다.
unordered가 붙고 안붙고의 차이는 이름 그대로 정렬여부이다.
map, set은 레드블랙 트리 기반으로 구현되어 있어서 데이터가 정렬되어 저장되며 O(logN)의 시간 복잡도를 가진다.
unordered_map, unordered_set은 정렬이 되어있지 않고 hash 값으로 탐색하기 때문에 O(1)의 시간 복잡도를 가진다.
unordered_map을 일반적인 hash table로 사용한다.
공통점은 중복값을 허용하지 않는다는 것이다. unordered_map을 hash table로 사용시 해시 충돌이 발생하지 않도록 주의 해야하고 해시 충돌을 허용하려면 unordered_multimap을 사용해야 한다.
map과 set의 차이는 value가 있느냐 없느냐이다.
set은 key와 value가 같은 map이라고 생각해도 된다.
unordered_map<string, int> hash_table;
// 모두 동일한 기능
hash_table.insert(make_pair("first", 1));
hash_table.insert({"second", 2});
hash_table["third"] = 3; // key에 third가 있는지 검사후 없으면 insert
key로 value에 접는하는것은 operator[] 또는 at을 이용하면 되지만 value로 key에 접근하는것은 모든 원소를 순회해서 찾아야 해서 비효율적이다.
그렇기 때문에 value를 key로 찾아야하는 일이 발생하면 key-value의 타입을 서로 바꾼 inverse map/set을 하나 더 생성해서 관리하면 된다.
value가 단순 인덱스의 역할을 한다면 inverse map/set 대신 vector 등의 배열을 이용하여 사용할 수도 있다.
+
BOJ 10816 (숫자 카드 2) 를 풀면서 나온 결과인데, unordered_set과 count를 이용하니 시간초과가 나오지만 vector를 한번 정렬시킨 후 이진탐색으로 개수를 찾아나가는건 정답처리가 되었다.
아무래도 값을 삽입하는 과정에서 해시충돌이 일어날 때 시간초과의 원인이 되는 것 같다.