|
|
|
@ -1,63 +1,50 @@
|
|
|
|
|
#ifndef MYTINYSTL_UNORDERED_SET_H_
|
|
|
|
|
#define MYTINYSTL_UNORDERED_SET_H_
|
|
|
|
|
|
|
|
|
|
// 这个头文件包含两个模板类 unordered_set 和 unordered_multiset
|
|
|
|
|
// 功能与用法与 set 和 multiset 类似,不同的是使用 hashtable 作为底层实现机制,容器中的元素不会自动排序
|
|
|
|
|
|
|
|
|
|
// notes:
|
|
|
|
|
//
|
|
|
|
|
// 异常保证:
|
|
|
|
|
// mystl::unordered_set<Key> / mystl::unordered_multiset<Key> 满足基本异常保证,对以下等函数做强异常安全保证:
|
|
|
|
|
// * emplace
|
|
|
|
|
// * emplace_hint
|
|
|
|
|
// * insert
|
|
|
|
|
|
|
|
|
|
#include "hashtable.h"
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
namespace mystl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 模板类 unordered_set,键值不允许重复
|
|
|
|
|
// 参数一代表键值类型,参数二代表哈希函数,缺省使用 mystl::hash,
|
|
|
|
|
// 参数三代表键值比较方式,缺省使用 mystl::equal_to
|
|
|
|
|
template <class Key, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
|
|
|
|
|
class unordered_set
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制
|
|
|
|
|
// 模板类 unordered_set,用于存储不允许重复的键值。
|
|
|
|
|
// 参数一代表键值类型,参数二代表哈希函数,默认使用 mystl::hash,
|
|
|
|
|
// 参数三代表键值比较方式,默认使用 mystl::equal_to。
|
|
|
|
|
template <class Key, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
|
|
|
|
|
class unordered_set
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制来存储数据。
|
|
|
|
|
typedef hashtable<Key, Hash, KeyEqual> base_type;
|
|
|
|
|
base_type ht_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type;
|
|
|
|
|
typedef typename base_type::key_type key_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef typename base_type::hasher hasher;
|
|
|
|
|
typedef typename base_type::key_equal key_equal;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type;
|
|
|
|
|
typedef typename base_type::difference_type difference_type;
|
|
|
|
|
typedef typename base_type::pointer pointer;
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer;
|
|
|
|
|
typedef typename base_type::reference reference;
|
|
|
|
|
typedef typename base_type::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::const_iterator iterator;
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator local_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator;
|
|
|
|
|
|
|
|
|
|
base_type ht_; // 实际存储数据的哈希表对象
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别定义
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type; // 分配器类型
|
|
|
|
|
typedef typename base_type::key_type key_type; // 键类型
|
|
|
|
|
typedef typename base_type::value_type value_type; // 值类型
|
|
|
|
|
typedef typename base_type::hasher hasher; // 哈希函数类型
|
|
|
|
|
typedef typename base_type::key_equal key_equal; // 键值比较函数类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type; // 大小类型
|
|
|
|
|
typedef typename base_type::difference_type difference_type; // 差异类型
|
|
|
|
|
typedef typename base_type::pointer pointer; // 指针类型
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer; // 常量指针类型
|
|
|
|
|
typedef typename base_type::reference reference; // 引用类型
|
|
|
|
|
typedef typename base_type::const_reference const_reference; // 常量引用类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::const_iterator iterator; // 迭代器类型
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator local_iterator; // 本地迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型
|
|
|
|
|
|
|
|
|
|
// 获取分配器
|
|
|
|
|
allocator_type get_allocator() const { return ht_.get_allocator(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、移动函数
|
|
|
|
|
|
|
|
|
|
// 默认构造函数,初始化哈希表为默认大小和哈希函数
|
|
|
|
|
unordered_set()
|
|
|
|
|
:ht_(100, Hash(), KeyEqual())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 自定义构造函数,允许指定桶的数量、哈希函数和键值比较函数
|
|
|
|
|
explicit unordered_set(size_type bucket_count,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
|
const KeyEqual& equal = KeyEqual())
|
|
|
|
@ -65,6 +52,7 @@ public:
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 范围构造函数,从输入迭代器范围中初始化
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
unordered_set(InputIterator first, InputIterator last,
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
@ -73,9 +61,10 @@ public:
|
|
|
|
|
: ht_(mystl::max(bucket_count, static_cast<size_type>(mystl::distance(first, last))), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (; first != last; ++first)
|
|
|
|
|
ht_.insert_unique_noresize(*first);
|
|
|
|
|
ht_.insert_unique_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 列表初始化构造函数
|
|
|
|
|
unordered_set(std::initializer_list<value_type> ilist,
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
@ -83,238 +72,341 @@ public:
|
|
|
|
|
:ht_(mystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_unique_noresize(*first);
|
|
|
|
|
ht_.insert_unique_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制构造函数
|
|
|
|
|
unordered_set(const unordered_set& rhs)
|
|
|
|
|
:ht_(rhs.ht_)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动构造函数
|
|
|
|
|
unordered_set(unordered_set&& rhs) noexcept
|
|
|
|
|
: ht_(mystl::move(rhs.ht_))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制赋值运算符
|
|
|
|
|
unordered_set& operator=(const unordered_set& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = rhs.ht_;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动赋值运算符
|
|
|
|
|
unordered_set& operator=(unordered_set&& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = mystl::move(rhs.ht_);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 列表赋值运算符
|
|
|
|
|
unordered_set& operator=(std::initializer_list<value_type> ilist)
|
|
|
|
|
{
|
|
|
|
|
ht_.clear();
|
|
|
|
|
ht_.reserve(ilist.size());
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_unique_noresize(*first);
|
|
|
|
|
ht_.insert_unique_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 析构函数
|
|
|
|
|
~unordered_set() = default;
|
|
|
|
|
|
|
|
|
|
// 迭代器相关
|
|
|
|
|
// 迭代器相关函数
|
|
|
|
|
|
|
|
|
|
// 返回指向容器开始的迭代器
|
|
|
|
|
iterator begin() noexcept { return ht_.begin(); }
|
|
|
|
|
const_iterator begin() const noexcept { return ht_.begin(); }
|
|
|
|
|
|
|
|
|
|
iterator begin() noexcept
|
|
|
|
|
{ return ht_.begin(); }
|
|
|
|
|
const_iterator begin() const noexcept
|
|
|
|
|
{ return ht_.begin(); }
|
|
|
|
|
iterator end() noexcept
|
|
|
|
|
{ return ht_.end(); }
|
|
|
|
|
const_iterator end() const noexcept
|
|
|
|
|
{ return ht_.end(); }
|
|
|
|
|
// 返回指向容器结束的迭代器
|
|
|
|
|
iterator end() noexcept { return ht_.end(); }
|
|
|
|
|
const_iterator end() const noexcept { return ht_.end(); }
|
|
|
|
|
|
|
|
|
|
const_iterator cbegin() const noexcept
|
|
|
|
|
{ return ht_.cbegin(); }
|
|
|
|
|
const_iterator cend() const noexcept
|
|
|
|
|
{ return ht_.cend(); }
|
|
|
|
|
// 返回指向容器开始的常量迭代器
|
|
|
|
|
const_iterator cbegin() const noexcept { return ht_.cbegin(); }
|
|
|
|
|
const_iterator cend() const noexcept { return ht_.cend(); }
|
|
|
|
|
|
|
|
|
|
// 容量相关
|
|
|
|
|
// 容量相关函数
|
|
|
|
|
|
|
|
|
|
// 判断容器是否为空
|
|
|
|
|
bool empty() const noexcept { return ht_.empty(); }
|
|
|
|
|
// 返回容器中元素的数量
|
|
|
|
|
size_type size() const noexcept { return ht_.size(); }
|
|
|
|
|
// 返回容器可以容纳的最大元素数量
|
|
|
|
|
size_type max_size() const noexcept { return ht_.max_size(); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 修改容器操作
|
|
|
|
|
|
|
|
|
|
// empalce / empalce_hint
|
|
|
|
|
|
|
|
|
|
// emplace / emplace_hint
|
|
|
|
|
// emplace 函数用于在容器中直接构造一个新元素,参数是构造函数需要的参数。
|
|
|
|
|
// emplace_hint 函数与 emplace 类似,但提供了一个迭代器 hint 作为插入位置的提示。
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
pair<iterator, bool> emplace(Args&& ...args)
|
|
|
|
|
{ return ht_.emplace_unique(mystl::forward<Args>(args)...); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_unique 函数,尝试插入一个新元素。
|
|
|
|
|
// mystl::forward 用于完美转发参数,保留参数的引用类型。
|
|
|
|
|
return ht_.emplace_unique(mystl::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
iterator emplace_hint(const_iterator hint, Args&& ...args)
|
|
|
|
|
{ return ht_.emplace_unique_use_hint(hint, mystl::forward<Args>(args)...); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_unique_use_hint 函数,尝试插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
return ht_.emplace_unique_use_hint(hint, mystl::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
|
|
|
|
|
// insert 函数用于将一个元素插入容器中,如果元素已存在则不插入。
|
|
|
|
|
pair<iterator, bool> insert(const value_type& value)
|
|
|
|
|
{ return ht_.insert_unique(value); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_unique 函数,尝试插入一个新元素。
|
|
|
|
|
return ht_.insert_unique(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<iterator, bool> insert(value_type&& value)
|
|
|
|
|
{ return ht_.emplace_unique(mystl::move(value)); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_unique 函数,尝试插入一个新元素。
|
|
|
|
|
// mystl::move 用于将右值引用转换为左值引用,避免不必要的复制。
|
|
|
|
|
return ht_.emplace_unique(mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator hint, const value_type& value)
|
|
|
|
|
{ return ht_.insert_unique_use_hint(hint, value); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_unique_use_hint 函数,尝试插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
return ht_.insert_unique_use_hint(hint, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator hint, value_type&& value)
|
|
|
|
|
{ return ht_.emplace_unique_use_hint(hint, mystl::move(value)); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_unique_use_hint 函数,尝试插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
// mystl::move 用于将右值引用转换为左值引用,避免不必要的复制。
|
|
|
|
|
return ht_.emplace_unique_use_hint(hint, mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
|
{ ht_.insert_unique(first, last); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_unique 函数,将一个范围内的元素插入容器中。
|
|
|
|
|
ht_.insert_unique(first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// erase / clear
|
|
|
|
|
|
|
|
|
|
// erase 函数用于从容器中删除元素。
|
|
|
|
|
void erase(iterator it)
|
|
|
|
|
{ ht_.erase(it); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase 函数,删除指定位置的元素。
|
|
|
|
|
ht_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void erase(iterator first, iterator last)
|
|
|
|
|
{ ht_.erase(first, last); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase 函数,删除指定范围内的元素。
|
|
|
|
|
ht_.erase(first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_type erase(const key_type& key)
|
|
|
|
|
{ return ht_.erase_unique(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase_unique 函数,删除指定键值的元素。
|
|
|
|
|
return ht_.erase_unique(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
|
{ ht_.clear(); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 clear 函数,清空容器中的所有元素。
|
|
|
|
|
ht_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void swap(unordered_set& other) noexcept
|
|
|
|
|
{ ht_.swap(other.ht_); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 swap 函数,交换两个容器的内容。
|
|
|
|
|
ht_.swap(other.ht_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找相关
|
|
|
|
|
|
|
|
|
|
// count 函数用于返回指定键值的元素个数。
|
|
|
|
|
size_type count(const key_type& key) const
|
|
|
|
|
{ return ht_.count(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 count 函数,返回指定键值的元素个数。
|
|
|
|
|
return ht_.count(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find 函数用于查找指定键值的元素,并返回指向该元素的迭代器。
|
|
|
|
|
iterator find(const key_type& key)
|
|
|
|
|
{ return ht_.find(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 find 函数,查找指定键值的元素。
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator find(const key_type& key) const
|
|
|
|
|
{ return ht_.find(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 find 函数,查找指定键值的元素。
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// equal_range 函数用于查找指定键值的元素范围,并返回一个迭代器对。
|
|
|
|
|
pair<iterator, iterator> equal_range(const key_type& key)
|
|
|
|
|
{ return ht_.equal_range_unique(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 equal_range_unique 函数,查找指定键值的元素范围。
|
|
|
|
|
return ht_.equal_range_unique(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<const_iterator, const_iterator> equal_range(const key_type& key) const
|
|
|
|
|
{ return ht_.equal_range_unique(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 equal_range_unique 函数,查找指定键值的元素范围。
|
|
|
|
|
return ht_.equal_range_unique(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket interface
|
|
|
|
|
|
|
|
|
|
// begin 函数用于返回指向指定桶的开始的迭代器。
|
|
|
|
|
local_iterator begin(size_type n) noexcept
|
|
|
|
|
{ return ht_.begin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 begin 函数,返回指向指定桶的开始的迭代器。
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator begin(size_type n) const noexcept
|
|
|
|
|
{ return ht_.begin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 begin 函数,返回指向指定桶的开始的迭代器。
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator cbegin(size_type n) const noexcept
|
|
|
|
|
{ return ht_.cbegin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 cbegin 函数,返回指向指定桶的开始的常量迭代器。
|
|
|
|
|
return ht_.cbegin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// end 函数用于返回指向指定桶的结束的迭代器。
|
|
|
|
|
local_iterator end(size_type n) noexcept
|
|
|
|
|
{ return ht_.end(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 end 函数,返回指向指定桶的结束的迭代器。
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator end(size_type n) const noexcept
|
|
|
|
|
{ return ht_.end(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 end 函数,返回指向指定桶的结束的迭代器。
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator cend(size_type n) const noexcept
|
|
|
|
|
{ return ht_.cend(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 cend 函数,返回指向指定桶的结束的常量迭代器。
|
|
|
|
|
return ht_.cend(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket_count 函数用于返回容器中的桶数量。
|
|
|
|
|
size_type bucket_count() const noexcept
|
|
|
|
|
{ return ht_.bucket_count(); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 bucket_count 函数,返回容器中的桶数量。
|
|
|
|
|
return ht_.bucket_count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// max_bucket_count 函数用于返回容器中允许的最大桶数量。
|
|
|
|
|
size_type max_bucket_count() const noexcept
|
|
|
|
|
{ return ht_.max_bucket_count(); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 max_bucket_count 函数,返回容器中允许的最大桶数量。
|
|
|
|
|
return ht_.max_bucket_count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket_size 函数用于返回指定桶中的元素数量。
|
|
|
|
|
size_type bucket_size(size_type n) const noexcept
|
|
|
|
|
{ return ht_.bucket_size(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 bucket_size 函数,返回指定桶中的元素数量。
|
|
|
|
|
return ht_.bucket_size(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket 函数用于返回指定键值所在的桶的索引。
|
|
|
|
|
size_type bucket(const key_type& key) const
|
|
|
|
|
{ return ht_.bucket(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 bucket 函数,返回指定键值所在的桶的索引。
|
|
|
|
|
return ht_.bucket(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// hash policy
|
|
|
|
|
|
|
|
|
|
// load_factor 函数用于返回容器的负载因子,即元素数量与桶数量的比值。
|
|
|
|
|
float load_factor() const noexcept { return ht_.load_factor(); }
|
|
|
|
|
|
|
|
|
|
// max_load_factor 函数用于获取或设置容器的最大负载因子。
|
|
|
|
|
float max_load_factor() const noexcept { return ht_.max_load_factor(); }
|
|
|
|
|
void max_load_factor(float ml) { ht_.max_load_factor(ml); }
|
|
|
|
|
|
|
|
|
|
// rehash 函数用于重新哈希容器,指定新的桶数量。
|
|
|
|
|
void rehash(size_type count) { ht_.rehash(count); }
|
|
|
|
|
|
|
|
|
|
// reserve 函数用于预留空间,指定容器需要容纳的元素数量。
|
|
|
|
|
void reserve(size_type count) { ht_.reserve(count); }
|
|
|
|
|
|
|
|
|
|
// hash_fcn 函数用于返回容器使用的哈希函数。
|
|
|
|
|
hasher hash_fcn() const { return ht_.hash_fcn(); }
|
|
|
|
|
key_equal key_eq() const { return ht_.key_eq(); }
|
|
|
|
|
|
|
|
|
|
// key_eq 函数用于返回容器使用的键值比较函数。
|
|
|
|
|
key_equal key_eq() const { return ht_.key_eq(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 重载相等操作符
|
|
|
|
|
friend bool operator==(const unordered_set& lhs, const unordered_set& rhs)
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 equal_range_unique 函数,比较两个容器的元素是否相等。
|
|
|
|
|
return lhs.ht_.equal_range_unique(rhs.ht_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载不等操作符
|
|
|
|
|
friend bool operator!=(const unordered_set& lhs, const unordered_set& rhs)
|
|
|
|
|
{
|
|
|
|
|
return !lhs.ht_.equal_range_unique(rhs.ht_);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
bool operator==(const unordered_set<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_set<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs == rhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
bool operator!=(const unordered_set<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_set<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs != rhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
void swap(unordered_set<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
unordered_set<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
}
|
|
|
|
|
// 调用底层哈希表的 equal
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************************/
|
|
|
|
|
|
|
|
|
|
// 模板类 unordered_multiset,键值允许重复
|
|
|
|
|
// 参数一代表键值类型,参数二代表哈希函数,缺省使用 mystl::hash,
|
|
|
|
|
// 参数三代表键值比较方式,缺省使用 mystl::equal_to
|
|
|
|
|
template <class Key, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
|
|
|
|
|
class unordered_multiset
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制
|
|
|
|
|
// 模板类 unordered_multiset,用于存储允许重复的键值。
|
|
|
|
|
// 参数一代表键值类型,参数二代表哈希函数,默认使用 mystl::hash,
|
|
|
|
|
// 参数三代表键值比较方式,默认使用 mystl::equal_to。
|
|
|
|
|
template <class Key, class Hash = mystl::hash<Key>, class KeyEqual = mystl::equal_to<Key>>
|
|
|
|
|
class unordered_multiset
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
// 使用 hashtable 作为底层机制来存储数据。
|
|
|
|
|
typedef hashtable<Key, Hash, KeyEqual> base_type;
|
|
|
|
|
base_type ht_;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type;
|
|
|
|
|
typedef typename base_type::key_type key_type;
|
|
|
|
|
typedef typename base_type::value_type value_type;
|
|
|
|
|
typedef typename base_type::hasher hasher;
|
|
|
|
|
typedef typename base_type::key_equal key_equal;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type;
|
|
|
|
|
typedef typename base_type::difference_type difference_type;
|
|
|
|
|
typedef typename base_type::pointer pointer;
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer;
|
|
|
|
|
typedef typename base_type::reference reference;
|
|
|
|
|
typedef typename base_type::const_reference const_reference;
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::const_iterator iterator;
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator local_iterator;
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator;
|
|
|
|
|
|
|
|
|
|
base_type ht_; // 实际存储数据的哈希表对象
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 使用 hashtable 的型别定义
|
|
|
|
|
typedef typename base_type::allocator_type allocator_type; // 分配器类型
|
|
|
|
|
typedef typename base_type::key_type key_type; // 键类型
|
|
|
|
|
typedef typename base_type::value_type value_type; // 值类型
|
|
|
|
|
typedef typename base_type::hasher hasher; // 哈希函数类型
|
|
|
|
|
typedef typename base_type::key_equal key_equal; // 键值比较函数类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::size_type size_type; // 大小类型
|
|
|
|
|
typedef typename base_type::difference_type difference_type; // 差异类型
|
|
|
|
|
typedef typename base_type::pointer pointer; // 指针类型
|
|
|
|
|
typedef typename base_type::const_pointer const_pointer; // 常量指针类型
|
|
|
|
|
typedef typename base_type::reference reference; // 引用类型
|
|
|
|
|
typedef typename base_type::const_reference const_reference; // 常量引用类型
|
|
|
|
|
|
|
|
|
|
typedef typename base_type::const_iterator iterator; // 迭代器类型
|
|
|
|
|
typedef typename base_type::const_iterator const_iterator; // 常量迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator local_iterator; // 本地迭代器类型
|
|
|
|
|
typedef typename base_type::const_local_iterator const_local_iterator; // 常量本地迭代器类型
|
|
|
|
|
|
|
|
|
|
// 获取分配器
|
|
|
|
|
allocator_type get_allocator() const { return ht_.get_allocator(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、移动函数
|
|
|
|
|
|
|
|
|
|
// 默认构造函数,初始化哈希表为默认大小和哈希函数
|
|
|
|
|
unordered_multiset()
|
|
|
|
|
:ht_(100, Hash(), KeyEqual())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 自定义构造函数,允许指定桶的数量、哈希函数和键值比较函数
|
|
|
|
|
explicit unordered_multiset(size_type bucket_count,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
|
const KeyEqual& equal = KeyEqual())
|
|
|
|
@ -322,6 +414,7 @@ public:
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 范围构造函数,从输入迭代器范围中初始化
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
unordered_multiset(InputIterator first, InputIterator last,
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
@ -330,9 +423,10 @@ public:
|
|
|
|
|
: ht_(mystl::max(bucket_count, static_cast<size_type>(mystl::distance(first, last))), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (; first != last; ++first)
|
|
|
|
|
ht_.insert_multi_noresize(*first);
|
|
|
|
|
ht_.insert_multi_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 列表初始化构造函数
|
|
|
|
|
unordered_multiset(std::initializer_list<value_type> ilist,
|
|
|
|
|
const size_type bucket_count = 100,
|
|
|
|
|
const Hash& hash = Hash(),
|
|
|
|
@ -340,195 +434,254 @@ public:
|
|
|
|
|
:ht_(mystl::max(bucket_count, static_cast<size_type>(ilist.size())), hash, equal)
|
|
|
|
|
{
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_multi_noresize(*first);
|
|
|
|
|
ht_.insert_multi_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制构造函数
|
|
|
|
|
unordered_multiset(const unordered_multiset& rhs)
|
|
|
|
|
:ht_(rhs.ht_)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动构造函数
|
|
|
|
|
unordered_multiset(unordered_multiset&& rhs) noexcept
|
|
|
|
|
: ht_(mystl::move(rhs.ht_))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制赋值运算符
|
|
|
|
|
unordered_multiset& operator=(const unordered_multiset& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = rhs.ht_;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 移动赋值运算符
|
|
|
|
|
unordered_multiset& operator=(unordered_multiset&& rhs)
|
|
|
|
|
{
|
|
|
|
|
ht_ = mystl::move(rhs.ht_);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 列表赋值运算符
|
|
|
|
|
unordered_multiset& operator=(std::initializer_list<value_type> ilist)
|
|
|
|
|
{
|
|
|
|
|
ht_.clear();
|
|
|
|
|
ht_.reserve(ilist.size());
|
|
|
|
|
for (auto first = ilist.begin(), last = ilist.end(); first != last; ++first)
|
|
|
|
|
ht_.insert_multi_noresize(*first);
|
|
|
|
|
ht_.insert_multi_noresize(*first); // 插入元素,不重新分配空间
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 析构函数
|
|
|
|
|
~unordered_multiset() = default;
|
|
|
|
|
|
|
|
|
|
// 迭代器相关函数
|
|
|
|
|
|
|
|
|
|
// 迭代器相关
|
|
|
|
|
// 返回指向容器开始的迭代器
|
|
|
|
|
iterator begin() noexcept { return ht_.begin(); }
|
|
|
|
|
const_iterator begin() const noexcept { return ht_.begin(); }
|
|
|
|
|
|
|
|
|
|
iterator begin() noexcept
|
|
|
|
|
{ return ht_.begin(); }
|
|
|
|
|
const_iterator begin() const noexcept
|
|
|
|
|
{ return ht_.begin(); }
|
|
|
|
|
iterator end() noexcept
|
|
|
|
|
{ return ht_.end(); }
|
|
|
|
|
const_iterator end() const noexcept
|
|
|
|
|
{ return ht_.end(); }
|
|
|
|
|
// 返回指向容器结束的迭代器
|
|
|
|
|
iterator end() noexcept { return ht_.end(); }
|
|
|
|
|
const_iterator end() const noexcept { return ht_.end(); }
|
|
|
|
|
|
|
|
|
|
const_iterator cbegin() const noexcept
|
|
|
|
|
{ return ht_.cbegin(); }
|
|
|
|
|
const_iterator cend() const noexcept
|
|
|
|
|
{ return ht_.cend(); }
|
|
|
|
|
// 返回指向容器开始的常量迭代器
|
|
|
|
|
const_iterator cbegin() const noexcept { return ht_.cbegin(); }
|
|
|
|
|
const_iterator cend() const noexcept { return ht_.cend(); }
|
|
|
|
|
|
|
|
|
|
// 容量相关
|
|
|
|
|
// 容量相关函数
|
|
|
|
|
|
|
|
|
|
// 判断容器是否为空
|
|
|
|
|
bool empty() const noexcept { return ht_.empty(); }
|
|
|
|
|
// 返回容器中元素的数量
|
|
|
|
|
size_type size() const noexcept { return ht_.size(); }
|
|
|
|
|
// 返回容器可以容纳的最大元素数量
|
|
|
|
|
size_type max_size() const noexcept { return ht_.max_size(); }
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
// 修改容器相关
|
|
|
|
|
|
|
|
|
|
// emplace / emplace_hint
|
|
|
|
|
|
|
|
|
|
// emplace 函数用于在容器中直接构造一个新元素,参数是构造函数需要的参数。
|
|
|
|
|
// emplace_hint 函数与 emplace 类似,但提供了一个迭代器 hint 作为插入位置的提示。
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
iterator emplace(Args&& ...args)
|
|
|
|
|
{ return ht_.emplace_multi(mystl::forward<Args>(args)...); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_multi 函数,尝试插入一个新元素。
|
|
|
|
|
// mystl::forward 用于完美转发参数,保留参数的引用类型。
|
|
|
|
|
return ht_.emplace_multi(mystl::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class ...Args>
|
|
|
|
|
iterator emplace_hint(const_iterator hint, Args&& ...args)
|
|
|
|
|
{ return ht_.emplace_multi_use_hint(hint, mystl::forward<Args>(args)...); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_multi_use_hint 函数,尝试插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::forward<Args>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// insert
|
|
|
|
|
|
|
|
|
|
// insert 函数用于将一个元素插入容器中,允许重复。
|
|
|
|
|
iterator insert(const value_type& value)
|
|
|
|
|
{ return ht_.insert_multi(value); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_multi 函数,插入一个新元素。
|
|
|
|
|
return ht_.insert_multi(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(value_type&& value)
|
|
|
|
|
{ return ht_.emplace_multi(mystl::move(value)); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_multi 函数,插入一个新元素。
|
|
|
|
|
// mystl::move 用于将右值引用转换为左值引用,避免不必要的复制。
|
|
|
|
|
return ht_.emplace_multi(mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator hint, const value_type& value)
|
|
|
|
|
{ return ht_.insert_multi_use_hint(hint, value); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_multi_use_hint 函数,插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
return ht_.insert_multi_use_hint(hint, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iterator insert(const_iterator hint, value_type&& value)
|
|
|
|
|
{ return ht_.emplace_multi_use_hint(hint, mystl::move(value)); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 emplace_multi_use_hint 函数,插入一个新元素。
|
|
|
|
|
// hint 作为插入位置的提示,可以提高插入效率。
|
|
|
|
|
// mystl::move 用于将右值引用转换为左值引用,避免不必要的复制。
|
|
|
|
|
return ht_.emplace_multi_use_hint(hint, mystl::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class InputIterator>
|
|
|
|
|
void insert(InputIterator first, InputIterator last)
|
|
|
|
|
{ ht_.insert_multi(first, last); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 insert_multi 函数,将一个范围内的元素插入容器中。
|
|
|
|
|
ht_.insert_multi(first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// erase / clear
|
|
|
|
|
|
|
|
|
|
// erase 函数用于从容器中删除元素。
|
|
|
|
|
void erase(iterator it)
|
|
|
|
|
{ ht_.erase(it); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase 函数,删除指定位置的元素。
|
|
|
|
|
ht_.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void erase(iterator first, iterator last)
|
|
|
|
|
{ ht_.erase(first, last); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase 函数,删除指定范围内的元素。
|
|
|
|
|
ht_.erase(first, last);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_type erase(const key_type& key)
|
|
|
|
|
{ return ht_.erase_multi(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 erase_multi 函数,删除指定键值的所有元素。
|
|
|
|
|
return ht_.erase_multi(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
|
{ ht_.clear(); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 clear 函数,清空容器中的所有元素。
|
|
|
|
|
ht_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void swap(unordered_multiset& other) noexcept
|
|
|
|
|
{ ht_.swap(other.ht_); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 swap 函数,交换两个容器的内容。
|
|
|
|
|
ht_.swap(other.ht_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找相关
|
|
|
|
|
|
|
|
|
|
// count 函数用于返回指定键值的元素个数。
|
|
|
|
|
size_type count(const key_type& key) const
|
|
|
|
|
{ return ht_.count(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 count 函数,返回指定键值的元素个数。
|
|
|
|
|
return ht_.count(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// find 函数用于查找指定键值的元素,并返回指向该元素的迭代器。
|
|
|
|
|
iterator find(const key_type& key)
|
|
|
|
|
{ return ht_.find(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 find 函数,查找指定键值的元素。
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator find(const key_type& key) const
|
|
|
|
|
{ return ht_.find(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 find 函数,查找指定键值的元素。
|
|
|
|
|
return ht_.find(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// equal_range 函数用于查找指定键值的元素范围,并返回一个迭代器对。
|
|
|
|
|
pair<iterator, iterator> equal_range(const key_type& key)
|
|
|
|
|
{ return ht_.equal_range_multi(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 equal_range_multi 函数,查找指定键值的元素范围。
|
|
|
|
|
return ht_.equal_range_multi(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pair<const_iterator, const_iterator> equal_range(const key_type& key) const
|
|
|
|
|
{ return ht_.equal_range_multi(key); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 equal_range_multi 函数,查找指定键值的元素范围。
|
|
|
|
|
return ht_.equal_range_multi(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket interface
|
|
|
|
|
|
|
|
|
|
// begin 函数用于返回指向指定桶的开始的迭代器。
|
|
|
|
|
local_iterator begin(size_type n) noexcept
|
|
|
|
|
{ return ht_.begin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 begin 函数,返回指向指定桶的开始的迭代器。
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator begin(size_type n) const noexcept
|
|
|
|
|
{ return ht_.begin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 begin 函数,返回指向指定桶的开始的迭代器。
|
|
|
|
|
return ht_.begin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator cbegin(size_type n) const noexcept
|
|
|
|
|
{ return ht_.cbegin(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 cbegin 函数,返回指向指定桶的开始的常量迭代器。
|
|
|
|
|
return ht_.cbegin(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// end 函数用于返回指向指定桶的结束的迭代器。
|
|
|
|
|
local_iterator end(size_type n) noexcept
|
|
|
|
|
{ return ht_.end(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 end 函数,返回指向指定桶的结束的迭代器。
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator end(size_type n) const noexcept
|
|
|
|
|
{ return ht_.end(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 end 函数,返回指向指定桶的结束的迭代器。
|
|
|
|
|
return ht_.end(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_local_iterator cend(size_type n) const noexcept
|
|
|
|
|
{ return ht_.cend(n); }
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 cend 函数,返回指向指定桶的结束的常量迭代器。
|
|
|
|
|
return ht_.cend(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket_count 函数用于返回容器中的桶数量。
|
|
|
|
|
size_type bucket_count() const noexcept
|
|
|
|
|
{ return ht_.bucket_count(); }
|
|
|
|
|
size_type max_bucket_count() const noexcept
|
|
|
|
|
{ return ht_.max_bucket_count(); }
|
|
|
|
|
|
|
|
|
|
size_type bucket_size(size_type n) const noexcept
|
|
|
|
|
{ return ht_.bucket_size(n); }
|
|
|
|
|
size_type bucket(const key_type& key) const
|
|
|
|
|
{ return ht_.bucket(key); }
|
|
|
|
|
|
|
|
|
|
// hash policy
|
|
|
|
|
|
|
|
|
|
float load_factor() const noexcept { return ht_.load_factor(); }
|
|
|
|
|
|
|
|
|
|
float max_load_factor() const noexcept { return ht_.max_load_factor(); }
|
|
|
|
|
void max_load_factor(float ml) { ht_.max_load_factor(ml); }
|
|
|
|
|
|
|
|
|
|
void rehash(size_type count) { ht_.rehash(count); }
|
|
|
|
|
void reserve(size_type count) { ht_.reserve(count); }
|
|
|
|
|
|
|
|
|
|
hasher hash_fcn() const { return ht_.hash_fcn(); }
|
|
|
|
|
key_equal key_eq() const { return ht_.key_eq(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
friend bool operator==(const unordered_multiset& lhs, const unordered_multiset& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs.ht_.equal_range_multi(rhs.ht_);
|
|
|
|
|
// 调用底层哈希表的 bucket_count 函数,返回容器中的桶数量。
|
|
|
|
|
return ht_.bucket_count();
|
|
|
|
|
}
|
|
|
|
|
friend bool operator!=(const unordered_multiset& lhs, const unordered_multiset& rhs)
|
|
|
|
|
|
|
|
|
|
// max_bucket_count 函数用于返回容器中允许的最大桶数量。
|
|
|
|
|
size_type max_bucket_count() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return !lhs.ht_.equal_range_multi(rhs.ht_);
|
|
|
|
|
// 调用底层哈希表的 max_bucket_count 函数,返回容器中允许的最大桶数量。
|
|
|
|
|
return ht_.max_bucket_count();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 重载比较操作符
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
bool operator==(const unordered_multiset<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_multiset<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs == rhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
bool operator!=(const unordered_multiset<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
const unordered_multiset<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
return lhs != rhs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重载 mystl 的 swap
|
|
|
|
|
template <class Key, class Hash, class KeyEqual, class Alloc>
|
|
|
|
|
void swap(unordered_multiset<Key, Hash, KeyEqual>& lhs,
|
|
|
|
|
unordered_multiset<Key, Hash, KeyEqual>& rhs)
|
|
|
|
|
{
|
|
|
|
|
lhs.swap(rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace mystl
|
|
|
|
|
#endif // !MYTINYSTL_UNORDERED_SET_H_
|
|
|
|
|
// bucket_size 函数用于返回指定桶中的元素数量。
|
|
|
|
|
size_type bucket_size(size_type n) const noexcept
|
|
|
|
|
{
|
|
|
|
|
// 调用底层哈希表的 bucket_size 函数,返回指定桶中的元素数量。
|
|
|
|
|
return ht_.bucket_size(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bucket 函数用于返回指定键值所在的桶的索引。
|
|
|
|
|
size_type bucket(const ke
|