STL—unordered_set和unordered_map使用及源码剖析

Posted _Karry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL—unordered_set和unordered_map使用及源码剖析相关的知识,希望对你有一定的参考价值。

文章目录

容器hashtable

概述

hashtable就是散列表(哈希表)
哈希表采用散列技术,散列技术是一种查找技术,而且是一种"一步到位"的查找技术

散列技术存储元素的时候是按照函数f对应的规律来存储元素,使得我们存储元素的位置为f(key)

顺序/二分/差值查找:要查找元素key->与待查找集合中的元素对比->找到要查找元素的位置index
散列查找:要查找元素key->直接通过函数f计算出要查找元素的位置index


hashtable最开始只有53个桶,当元素个数大于桶的个数时,桶的数目扩大为最接近当前桶数两倍的质数,实际上,桶数目的增长顺序被写死在代码里:

static const unsigned long __stl_prime_list[__stl_num_primes] = 
        53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
        49157, 98317, 196613, 393241, 786433, 1572869, 3145739,
        6291469, 12582917, 25165843, 50331653, 100663319,
        201326611, 402653189, 805306457, 1610612741,
        3221225473ul, 4294967291ul;

源码剖析

template<class Value, 	//节点的实值类别
		 class Key, 	//节点的键值类别
		 class HashFcn,	//hash function的函数类别
         class ExtractKey, //从节点中取出键值的方法(仿函数)
		 class EqualKey,	//判断键值是否相同(仿函数)
         class Alloc=alloc>	//空间配置器
class hashtable 
public:
    typedef HashFcn 	hasher;
    typedef EqualKey 	key_equal;
    typedef size_t 		size_type;
private:
    hasher hash;
    key_equal equals;
    ExtractKey get_key;
    
    typedef __hashtable_node<Value> node;
    vector<node*, Alloc> buckets;	// 保存桶的vector
    size_type num_elements;
public:
    size_type bucket_count() const  return buckets.size(); 
;

// 节点
template<class Value>
struct __hashtable_node 
    __hashtable_node *next;
    Value val;
;

// 迭代器
template<class Value, class Key, class HashFen, class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_iterator 
    node *cur;
    hashtable *ht;
;

hashtable使用

hashtable<pair<const string, int>, 
		  string, 
		  hash<string>, 
		  select1st<pair<const string, int>>, 
		  equal_to<string>, 
		  alloc> siht(100, hash<string>(), equal_to<string>());

cout << siht.size() << endl; 							// 0
cout << siht.bucket_count() << endl;					// 193
siht.insert_unique(make_pair(string("jjhou"), 95));
siht.insert_unique(make_pair(string("sabrina"), 90));
siht.insert_unique(make_pair(string("mjchen"), 85));
cout << siht.size() << endl;							// 3
cout << siht.bucket_count() << endl;					// 193
cout << siht.find(string("sabrina"))->second << endl; 	//90
cout << siht.find(string("jjhou"))->second << endl;		//95
cout << siht.find(string("mjchen"))->second << endl;	//85
#include <iostream>
#include <hash_set>
using namespace std;
int main()

	//hash_table
	//<value, key, hash_func, extract-key, equal-key, allocator>
	//note: hash_table has no default ctor
	hashtable<int, int, hash<int>, identity<int>, equal_to<int>, alloc>
		iht(50, hash<int>, euqal_to<int>);	//指定50个buckets
	cout << iht.size() << endl;		//0
	cout << iht.bucket_count() << endl;	//53
	cout << iht.max_bucket_count() << endl;	// 4294967291
	
	iht.insert_unique(59);
	iht.insert_unique(63);
	iht.insert_unique(108);
	iht.insert_unique(2);
	iht.insert_unique(53);
	iht.insert_unique(55);
	
	cout << iht.size() << endl;	//6

	//声明一个hashtable迭代器,将所有节点值打印出来
	hashtable<int, int, hash<int>, identity<int>, equal_to<int>, alloc>
		::iterator ite = iht.begin();
	for(int i = 0; i < iht.size(); ++i, ++ite)
		cout << *ite << ' '; // 53 55 2 108 59 63
	cout << endl;
	
	//遍历所有buckets,如果其节点个数不为0,就打印出节点个数
	for(int i = 0; i < iht.bucket_count(); ++i)
	
		int n = iht.elems_in_bucket(i);
		if(n != 0)
			cout << "bucket[ " << i << " ] has " << n << " elems." << endl;
	
	//bucket[0] has 1 elems.
	//bucket[2] has 3 elems.
	//bucket[6] has 1 elems.
	//bucket[10] has 1 elems.

容器unordered_set、unordered_multiset、unordered_map和unordered_multimap

概述

C++11引入的容器unordered_setunordered_multisetunordered_mapunordered_multimap更名自gcc2.9的容器hash_sethash_multisethash_maphash_multimap,其底层封装了hashtable.用法与setmultisetmapmultimap类似

以上是关于STL—unordered_set和unordered_map使用及源码剖析的主要内容,如果未能解决你的问题,请参考以下文章

C++源码剖析——unordered_map和unordered_set

STL详解—— unordered_setunordered_map的介绍及使用

cpp►STL容器->哈希容器->unordered_set

STL学习笔记— —无序容器(Unordered Container)

leetcode-3 无重复字符的最长字串(滑动窗口,unordered_set, st.find(string[i]))

leetcode-3 无重复字符的最长字串(滑动窗口,unordered_set, st.find(string[i]))