当前位置: 首页 > news >正文

unordered_map和unordered_set的封装与简单测试

//hashtable.h

#pragma once
#include <string>
#include <vector>
using namespace std;
template<class K>
struct HashFunc
{size_t operator()(const K& key){return (size_t)key;}
};
// 特化 
template<>
struct HashFunc<string>
{size_t operator()(const string& key){size_t hash = 0;for (auto e : key){hash *= 131;hash += e;}return hash;}
};
namespace Hash_Bucket {template<class	T>struct LHashNode {LHashNode(const T& t):_data(t), _next(nullptr){}T _data;LHashNode<T>* _next;};template<class K, class T, class KeyOfT, class Hash>class HashTable;template<class K, class T, class Ptr, class Ref, class KeyOfT, class Hash>struct HTIterator {typedef LHashNode<T> Node;typedef HTIterator<K, T, Ptr, Ref, KeyOfT, Hash> Self;Node* _node;const HashTable<K, T, KeyOfT, Hash>* _pht;HTIterator(Node* node, const HashTable<K, T, KeyOfT, Hash>* pht):_node(node), _pht(pht){}Ref operator*() {return _node->_data;}Ptr operator->() {return &_node->_data;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}Self operator++(){if (_node->_next) {_node = _node->_next;}else {KeyOfT kot;Hash hash;size_t index = hash(kot(_node->_data)) % (_pht->_table.size());index++;while (index < _pht->_table.size() && _pht->_table[index] == nullptr) {index++;}if (index == _pht->_table.size()) {_node = nullptr;}else {_node = _pht->_table[index];}}return *this;}};template<class K, class T, class KeyOfT, class Hash>class HashTable {public:typedef LHashNode<T> Node;// 让迭代器能访问HashTable的私有成员template<class K, class T, class Ptr, class Ref, class KeyOfT, class Hash>friend struct HTIterator;typedef HTIterator<K, T, T*, T&, KeyOfT, Hash> Iterator;typedef HTIterator<K, T, const T*, const T&, KeyOfT, Hash> ConstIterator;//迭代器相关接口Iterator Begin() {for (size_t i = 0; i < _table.size(); i++) {if (_table[i]) {return Iterator(_table[i], this);}}return End();}Iterator End() {return Iterator(nullptr, this);}ConstIterator Begin() const{if (_size == 0)return End();for (size_t i = 0; i < _table.size(); i++){Node* cur = _table[i];if (cur){return ConstIterator(cur, this);}}return End();}ConstIterator End() const{return ConstIterator(nullptr, this);}inline unsigned long __stl_next_prime(unsigned long n){// Note: assumes long is at least 32 bits.static const int __stl_num_primes = 28;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, 3221225473, 4294967291};const unsigned long* first = __stl_prime_list;const unsigned long* last = __stl_prime_list +__stl_num_primes;const unsigned long* pos = lower_bound(first, last, n);return pos == last ? *(last - 1) : *pos;}HashTable() {_table.resize(__stl_next_prime(0), nullptr);_size = 0;}~HashTable() {for (size_t i = 0; i < _table.size(); i++) {Node* cur = _table[i];while (cur) {Node* next = cur->_next;delete cur;cur = next;}_table[i] = nullptr;}_size = 0;}pair<Iterator, bool> Insert(const T& data) {KeyOfT kot;Hash hash;Iterator it = Find(kot(data));if (it != End())return make_pair(it, false);//扩容if (_size == _table.size()) {vector<Node*> newtable;newtable.resize(__stl_next_prime(_table.size() + 1), nullptr);for (size_t i = 0; i < _table.size(); i++) {Node* cur = _table[i];while (cur) {size_t hash0 = hash(kot(cur->_data)) % newtable.size();Node* next = cur->_next;cur->_next = newtable[hash0];newtable[hash0] = cur;cur = next;}_table[i] = nullptr;}_table.swap(newtable);}size_t hash0 = hash(kot(data)) % _table.size();Node* newnode = new Node(data);//头插法newnode->_next = _table[hash0];_table[hash0] = newnode;_size++;return make_pair(Iterator(newnode, this), true);}Iterator Find(const K& key){Hash hash;KeyOfT kot;size_t hash0 = hash(key) % _table.size();Node* cur = _table[hash0];while (cur) {if (kot(cur->_data) == key) {return Iterator(cur, this);}cur = cur->_next;}return End();}bool Erase(const K& key) {Hash hash;KeyOfT kot;size_t hash0 = hash(key) % _table.size();Node* cur = _table[hash0];Node* prev = nullptr;while (cur) {if (kot(cur -> _data) == key) {if (prev == nullptr) {_table[hash0] = cur->_next;}else {prev->_next = cur->_next;}delete cur;_size--;return true;}prev = cur;cur = cur->_next;}return false;}size_t Size() const {return _size;}private:vector<Node*> _table;size_t _size;};}

//unordered_map.h

#pragma once
#include "HashTable.h"
namespace  my_unordered_map {template<class K, class V, class Hash = HashFunc<K>>class unordered_map {struct MapKeyOfT{const K& operator()(const pair<K, V>& kv){return kv.first;}};public:typedef typename Hash_Bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash>::Iterator iterator;typedef typename Hash_Bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash>::ConstIterator const_iterator;iterator begin(){return _ht.Begin();}iterator end(){return _ht.End();}const_iterator begin() const{return _ht.Begin();}const_iterator end() const{return _ht.End();}pair<iterator, bool> insert(const pair<K, V>& kv){return _ht.Insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));return ret.first->second;}iterator Find(const K& key){return _ht.Find(key);}bool Erase(const K& key){return _ht.Erase(key);}private:Hash_Bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash> _ht;};
}

//unordered_set.h

#pragma once
#include "HashTable.h"
namespace my_unordered_set
{template<class K, class Hash = HashFunc<K>>class unordered_set{struct SetKeyOfT{const K& operator()(const K& key){return key;}};public:typedef typename Hash_Bucket::HashTable<K, const K, SetKeyOfT, Hash>::Iterator iterator;typedef typename Hash_Bucket::HashTable<K, const K, SetKeyOfT, Hash>::ConstIterator const_iterator;iterator begin(){return _ht.Begin();}iterator end(){return _ht.End();}const_iterator begin() const{return _ht.Begin();}const_iterator end() const{return _ht.End();}pair<iterator, bool> insert(const K& key){return _ht.Insert(key);}iterator Find(const K& key){return _ht.Find(key);}bool Erase(const K& key){return _ht.Erase(key);}private:Hash_Bucket::HashTable<K, const K, SetKeyOfT, Hash> _ht;};
}

//test.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
//#include "unordered_map.h"
//
//int main() {
//    // 测试插入和遍历
//    my_unordered_map::unordered_map<string, int> um;
//    um.insert({ "apple", 1 });
//    um.insert({ "banana", 2 });
//    um.insert({ "cherry", 3 });
//    cout << "插入后元素:" << endl;
//    for (auto& p : um) {
//        cout << p.first << ":" << p.second << " ";
//    }
//    cout << endl;  // 输出顺序不确定,取决于哈希函数
//
//    // 测试operator[]
//    um["date"] = 4;
//    cout << "um[\"date\"] = " << um["date"] << endl;  // 输出4
//
//    // 测试查找
//    auto it = um.Find("banana");
//    if (it != um.end()) {
//        cout << "找到banana:" << it->second << endl;  // 输出2
//    }
//
//    // 测试删除
//    bool erased = um.Erase("apple");
//    cout << "删除apple:" << (erased ? "成功" : "失败") << endl;  // 输出成功
//    it = um.Find("apple");
//    if (it == um.end()) {
//        cout << "确认删除apple:成功" << endl;
//    }
//
//    // 测试遍历删除后元素
//    cout << "删除后元素:" << endl;
//    for (auto& p : um) {
//        cout << p.first << ":" << p.second << " ";
//    }
//    cout << endl;
//
//    return 0;
//}
#include "unordered_set.h"int main() {// 测试插入和遍历my_unordered_set::unordered_set<int> us;us.insert(10);us.insert(20);us.insert(30);us.insert(20);  // 重复插入,应失败cout << "插入后元素(无序):";for (auto it = us.begin(); it != us.end(); ++it) {cout << *it << " ";}cout << endl;  // 可能输出:10 20 30(顺序取决于哈希函数)// 测试查找auto it = us.Find(20);if (it != us.end()) {cout << "找到元素:" << *it << endl;  // 输出20}it = us.Find(40);if (it == us.end()) {cout << "未找到元素40" << endl;}// 测试删除bool erased = us.Erase(20);cout << "删除20:" << (erased ? "成功" : "失败") << endl;  // 输出成功it = us.Find(20);if (it == us.end()) {cout << "确认删除20:成功" << endl;}// 测试删除后遍历cout << "删除后元素:";for (auto val : us) {  // 范围for依赖迭代器cout << val << " ";}cout << endl;  // 可能输出:10 30// 测试字符串类型my_unordered_set::unordered_set<string> us_str;us_str.insert("apple");us_str.insert("banana");us_str.insert("cherry");cout << "字符串集合元素:";for (const auto& s : us_str) {cout << s << " ";}cout << endl;return 0;
}

http://www.dtcms.com/a/499509.html

相关文章:

  • (Kotlin协程十六)try/catch 可以捕获子协程的异常吗?为什么?
  • 网站移动端怎么做的做外国网站怎么买空间
  • 图像的脉冲噪声和中值滤波
  • 3.4特殊矩阵的压缩存储
  • SpringAI+DeepSeek大模型应用开发
  • 递归-24.两两交换链表中的节点-力扣(LeetCode)
  • 【Java零基础·第12章】Lambda与Stream API
  • Qemu-NUC980(八):GPIO Controller
  • 外贸型企业网站建设开源商城源码
  • JS逆向-安全辅助项目Yakit热加载魔术方法模版插件语法JSRpc进阶调用接口联动
  • 使用IOT-Tree接入各种数据转BACnet模拟设备输出
  • 网站搭建说明北京海淀区是几环
  • 基于多模态AI技术的传统行业智能化升级路径研究——以开源AI大模型、AI智能名片与S2B2C商城小程序为例
  • 【C语言进阶】指针进阶_数组指针的使用,数组参数和指针参数
  • PySide6 控件插入日期时间(QDateTime)
  • 网站建设 jsp php垂直网站建设
  • 招商网站大全企业官方网站建设的流程
  • 征程 6 | 工具链如何支持 Matmul/Conv 双 int16 输入量化?
  • 【案例实战】鸿蒙分布式调度:跨设备协同实战
  • 中英文网站设计网站开发投标文件
  • Langgraph译文1:让AI自主决策的代理架构
  • 如何让百度能查到自己衡阳专业的关键词优化终报价
  • 为什么.NET的System.IO.Compression无法解压zlib流
  • 微信小程序:日常零售供应系统
  • 安卓如何查看settings是被哪个进程更新的?相关dumpsys命令剖析
  • 网络营销方式案例分析郑州网站优化推广
  • 下载软件太慢的加速操作
  • 网站改版技术要求git wordpress中文免费主题
  • 从应力到位移:混合模式分层损伤起始点推导
  • Gartner 2025年新兴技术成熟度曲线