[해시(Hash)] STL 제공 해시 함수 객체: std::hash 및 해시 컨테이너: std::unordered_map/set

Jin Hur·2022년 1월 6일
1

reference: "전문가를 위한 C++" / 마크 그레고리

std::hash 템플릿 함수 객체

  • C++는 문자열을 비롯해 모든 기본 데이터 타입에 대한 해시 값을 생성하는 기능을 제공
  • 객체 내부에 해시 함수 알고리즘이 구현

reference: https://www.delftstack.com/ko/howto/cpp/hash-in-cpp/

#include <iostream>
#include <iomanip>
#include <functional>
#include <vector>

using std::cout; using std::endl;
using std::setw; using std::string;

int main() {
    string str1("arbitrary string");
    std::vector<string> vec2 = { "true", "false", "false", "true", "false", "true" };

    std::hash<string> str_hash;

    cout << "str_hash(\"" << str1 << "\") => " << str_hash(str1) << endl;

    for (const auto& item : vec2) {
        cout << "str_hash(\"" << item << "\") => " << str_hash(item) << endl;
    }

    return EXIT_SUCCESS;
}

std::hash 템플릿 클래스는 STL의 <functional> 헤더에서 제공된다. string 인수 뿐 아니라 주어진 템플릿 인수로 해시 함수 객체를 생성하고, operator()를 사용하여 size_t값을 반환하며 해시 값을 생성한다.


std::unordered_set/map 해시 컨테이너

  • 체이닝을 사용하는 해시 테이블에서 구현했던 해시 테이블 코드를 템플릿 형태로 바꾸면 모든 데이터 타입에 대해 사용할 수 있는 형태로 만들 수 있음
  • STL은 이러한 기능을 std::unordered_set<Key>와 std::unordered_map<Key, Value> 형태로 미리 구현하여 제공한다. _set은 키만 저장할 수 있고, _map은 키와 값을 함께 저장할 수 있다.
  • 두 컨테이너 모두 체이닝을 사용하는 해시 테이블로 구현
  • 해시 테이블의 각 행은 키 또는 키/값의 쌍을 저장하는 벡터이고, 벡터의 각 버킷에 저장하는 값은 그 인덱스를 해시 값으로 하는 연결 리스트의 첫 번째 노드(node)에 대한 참조
  • 데이터가 없는 버킷은 널(null)을 가리킨다.

부하율과 재해싱

  • 기본적으로 이들 컨테이너는 최대 1의 부하율을 가짐
  • 해시 테이블보다 원소 개수가 많아지게 되면 곧바로 해시 테이블 크기를 키우고, 해시 함수를 변경하는 재해싱이 일어남. 그 결과 부하율은 1보다 작아지게 됨
  • 사용자가 강제로 rehash() 함수를 호출하여 재해싱을 할 수도 있고, max_load_factor(float) 함수를 사용하여 기본값이 1로 되어있는 부하율 최대 한계치를 변경할 수도 있음
    • 부하율이 지정된 한계치를 넘어가면 재해싱 발생

참조 연산자 []

  • 참조연산자 []와 키를 통해 값을 받아올 수 있다.
  • 이 연산자는 값에 대한 참조를 반환하므로 이를 이용하여 저장된 값을 변경할 수도 있다.
  • 만약 해당 키가 없다면 해당 위치에 기본값을 추가하여 반환한다.
    • 기본 값은 0이다.

기타 메서드

  • rehash(): 재해싱 강제
  • load_factor(): 현재 부하율 반환
  • max_load_factor(float): 부하율 최대 한계치 변경
  • bucket_count(): 현재 버킷의 갯수 반환

시간 복잡도

  • 부하율을 최대 1로 유지한다고 해서 모든 키에 대한 룩업/삭제 연산이 O(1)을 보장하는 것은 아니다. 부하율은 단순히 특정 버킷에 해당하는 리스트들의 평균 길이(키 갯수/버킷 갯수)일 뿐이다. 만약 해시 함수가 적절하지 못하다면 룩업/삭제 연산에 있어 O(1) 이상의 시간이 소요된다.

해시 함수가 중복되지 않는, 골고루 해시 값을 반환해주고(= 해시 충돌이 거의 X), 부하율이 1 이하라면

  • 삽입 시간 복잡도: O(1)
    • 반면 map 같은 경우 정렬이 이루어져야 하기에 O(logN)
  • 룩업/삭제 시간 복잡도: O(1)

해시 함수가 적절치 못하여 해시 충돌이 자주 발행하는 경우

  • 삽입 시간 복잡도: O(1)
  • 룩업/삭제 시간 복잡도: (최악)O(N)

multiset/map

  • unordered_set과 unordered_map은 중복 키를 허용하지 않는다. 만약 중복된 키를 저장하고 싶다면, unordered_multiset과 unordered_multimap을 사용해야 한다.
  • 이 두 컨테이너의 삽입 함수는 주어진 키가 이미 존재하는지를 검사하지 않는다.
  • 특정 키에 해당하는 모든 값을 얻을 수 있는 기능도 지원한다.

사용자 자료형이 키가 될 때

  • to be ..

1개의 댓글

comment-user-thumbnail
2025년 8월 27일

https://www.globhy.com/article/buying-horizontal-carbonized-bamboo-flooring-from-china-while-living-in-new-york
https://www.globhy.com/article/why-bamboo-flooring-is-the-eco-friendly-champion-of-sustainable-homes
https://www.hentai-foundry.com/user/bothbest/blogs/20350/Choosing-Bamboo-Flooring-for-My-London-Home
https://yamap.com/users/4784209
https://forum.iscev2024.ca/member.php?action=profile&uid=1357
https://my.usaflag.org/members/bothbest/profile/
https://myliveroom.com/bothbest
https://forum.geckos.ink/member.php?action=profile&uid=642
https://competitorcalendar.com/members/bothbest/profile/
https://www.fruitpickingjobs.com.au/forums/users/bothbest/
https://thefwa.com/profiles/bamboo-flooring
https://chanylib.ru/ru/forum/user/9508/
https://greenteam.app/bothbest
http://www.v0795.com/home.php?mod=space&uid=2304271
https://wearedevs.net/profile?uid=201358
https://www.templepurohit.com/forums/users/chinahousehold/
https://tutorialslink.com/member/FlooringBamboo/68089
https://www.tkaraoke.com/forums/profile/bothbest/
https://www.aipictors.com/users/bothbest
https://forum.index.hu/User/UserDescription?u=2129081
http://programujte.com/profil/75582-chinabamboo/
https://lamsn.com/home.php?mod=space&uid=1290622
https://nexusstem.co.uk/community/profile/chinabamboo/
https://brain-market.com/u/chinabamboo
https://malt-orden.info/userinfo.php?uid=414587
https://www.halaltrip.com/user/profile/255692/chinabamboo/
https://goodgame.ru/user/1698091
https://vcook.jp/users/42177
https://library.zortrax.com/members/china-bamboo/
https://aprenderfotografia.online/usuarios/chinabamboo/profile/
https://plaza.rakuten.co.jp/chinabamboo/
https://plaza.rakuten.co.jp/chinabamboo/diary/202508270000/
https://plaza.rakuten.co.jp/chinabamboo/diary/202508270001/
https://eternagame.org/players/538402
https://www.slmath.org/people/82724
https://www.aipictors.com/users/chinabambooflooring
https://vocal.media/authors/china-bamboo-bfc
https://www.giantbomb.com/profile/chinabamboo/
https://www.keedkean.com/member/44724.html?type=profile

답글 달기