commit 77b0d6f6de501712d58902394ded4012c7700f59 Author: mmlhbjk Date: Sat Sep 28 02:21:54 2024 +0800 博客 https://blog.lenyiin.com/unordered-set-map/ 的代码仓库 diff --git a/Linux/HashTable.hpp b/Linux/HashTable.hpp new file mode 100644 index 0000000..a40575e --- /dev/null +++ b/Linux/HashTable.hpp @@ -0,0 +1,685 @@ +#pragma once + +#include +#include +#include + +// unordered_set -> HashTable +// unordered_map -> HashTable> + +namespace Lenyiin +{ + template + struct SetKeyOfT + { + const K &operator()(const K &key) + { + return key; + } + }; + + enum State + { + EMPTY, // 槽位为空 + EXIST, // 槽位已经存在一个元素 + DELETE // 槽位中元素被删除 + }; + + template + struct HashData + { + T _data; + State _state; + + HashData() + : _data(T()), _state(EMPTY) + { + } + }; + + template + class Close_HashTable + { + private: + typedef struct HashData HashData; + + size_t SecondHash(const K &key, size_t table_size) + { + return 1 + (key % (table_size - 1)); + } + + public: + // 负载因子 = 表中数据/表的大小 衡量哈希表满的程度 + // 表越接近满, 插入数据越容易冲突, 冲突越多, 效率越低 + // 哈希表并不是满了才增容, 开放定制法中, 一般负载因子到 0.7 左右就开始增容 + // 负载因子越小, 冲突概率越低, 整体效率越高, 但是负载因子越小, 浪费的空间越大, 所以负载因子一般取一个折中的值 + void CheckCapacity() + { + KeyOfT koft; + + // // version 1 + // if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + // { + // // 增容 + // // 1. 开 2倍大小的新表 + // // 2. 遍历旧表的数据,重新计算在新表中位置 + // // 3. 释放旧表 + // std::vector newtables; + // size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // newtables.resize(newsize); + // for (size_t i = 0; i < _tables.size(); i++) + // { + // if (_tables[i]._state == EXIST) + // { + // // 计算在新表中的位置, 并处理冲突 + // size_t index = koft(_tables[i]._data) % newtables.size(); + // while (newtables[index]._state == EXIST) + // { + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + // newtables[index] = _tables[i]; + // } + // } + // _tables.swap(newtables); + // } + + // // version 2 + // if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + // { + // // 增容 + // // 1. 开 2倍大小的新表 + // // 2. 遍历旧表的数据,重新计算在新表中位置 + // // 3. 释放旧表 + // std::vector newtables; + // size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // newtables.resize(newsize); + // for (size_t i = 0; i < _tables.size(); i++) + // { + // if (_tables[i]._state == EXIST) + // { + // // 重新计算新表中的位置 + // size_t index = koft(_tables[i]._data) % newtables.size(); + // size_t step = SecondHash(koft(_tables[i]._data), newtables.size()); + + // // 处理冲突:双重哈希探测 + // while (newtables[index]._state == EXIST) + // { + // index = (index + step) % newtables.size(); + // } + + // // 插入元素到新表 + // newtables[index] = _tables[i]; + // } + // } + // _tables.swap(newtables); + // } + + // version 3 + // 另一种增容思路 + if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + { + Close_HashTable newht; + size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + newht._tables.resize(newsize); + for (size_t i = 0; i < _tables.size(); i++) + { + if (_tables[i]._state == EXIST) + { + newht.Insert(_tables[i]._data); + } + } + _tables.swap(newht._tables); + } + } + + bool Insert(const T &data) + { + KeyOfT koft; + + CheckCapacity(); + // 闭散列中线性探测有什么问题? + // 线性探测思路就是我的位置被占了, 我就挨着往后去占别人的位置, 可能会导致一片一片的冲突, 洪水效应 + + // version 1 + // 线性探测 + // 计算 data 中的 key 在表中映射的位置 + // size_t index = koft(data) % _tables.size(); + // while (_tables[index]._state == EXIST) + // { + // if (koft(_tables[index]._data) == koft(data)) + // { + // return false; // 已经存在 + // } + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + + // version 2 + // 二次探测 + // 计算 data 中的 key 在表中映射的位置 + // size_t start = koft(data) % _tables.size(); + // size_t index = start; + // int i = 0; + // while (_tables[index]._state == EXIST) + // { + // if (koft(_tables[index]._data) == koft(data)) + // { + // return false; // 已经存在 + // } + // index = start + i * i; + // i++; + // index %= _tables.size(); + // } + + // version 3 + // 双重哈希 + size_t index = koft(data) % _tables.size(); + size_t step = SecondHash(koft(data), _tables.size()); + while (_tables[index]._state == EXIST) + { + if (koft(_tables[index]._data) == koft(data)) + { + return false; // 如果找到相同的 key,插入失败 + } + + index = (index + step) % _tables.size(); // 使用双重哈希计算下一个位置 + } + + _tables[index]._data = data; + _tables[index]._state = EXIST; + ++_num; + + // 我么可以看到闭散列-开放定制法不是一种好的解决方式, 因为它是一种我的位置被占了, 我就去抢占别人的位置的思路 + // 也就是说他的哈希冲突会相互影响, 我冲突占你的, 你冲突占他的, 他冲突了... , 没完没了, 整体的效率都变低了 + // 开散列的哈希桶可以解决上面的问题 + return true; + } + + // 线性探测 + // HashData *Find(const K &key) + // { + // KeyOfT koft; + // // 计算 data 中的 key 在表中映射的位置 + // size_t index = key % _tables.size(); + // while (_tables[index]._state != EMPTY) + // { + // if (koft(_tables[index]._data) == key) + // { + // if (_tables[index]._state == EXIST) + // { + // return &_tables[index]; + // } + // else if (_tables[index]._state == DELETE) + // { + // return nullptr; + // } + // } + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + // return nullptr; + // } + + // 双重哈希 + HashData *Find(const K &key) + { + KeyOfT koft; + size_t index = key % _tables.size(); + size_t step = SecondHash(key, _tables.size()); // 计算步长 + while (_tables[index]._state != EMPTY) + { + if (koft(_tables[index]._data) == key) + { + if (_tables[index]._state == EXIST) + { + return &_tables[index]; + } + else if (_tables[index]._state == DELETE) + { + return nullptr; + } + } + + index = (index + step) % _tables.size(); // 使用双重哈希探测下一个位置 + } + + return nullptr; + } + + bool Erase(const K &key) + { + HashData *ret = Find(key); + if (ret) + { + ret->_state = DELETE; + --_num; + return true; + } + else + { + return false; + } + } + + HashData &getHashData(int pos) + { + return _tables[pos]; + } + + void Print() + { + int size = _tables.size(); + for (int i = 0; i < size; i++) + { + std::cout << i << "\t"; + } + std::cout << std::endl; + + for (int i = 0; i < size; i++) + { + auto cur = _tables[i]; + if (cur._state == EXIST) + { + std::cout << cur._data << "\t"; + } + else + { + std::cout << "*\t"; + } + } + std::cout << "\n\n"; + } + + private: + std::vector _tables; + size_t _num = 0; // 存储了几个有效数据 + }; + + template + struct HashNode + { + T _data; // 存储数据 + HashNode *_next; // 存储下一个节点 + + // 如果想要实现迭代顺序为插入顺序, 可以加两个指针组成一个链表 + // HashNode* _linknext; + // HashNode* _linkprev; + + HashNode(const T &data) + : _data(data), _next(nullptr) + { + } + }; + + // 前置声明 + template + class Open_HashTable; + + // 哈希表只有单向迭代器, 只有 ++, 没有-- + template + struct __HashTableIterator + { + typedef __HashTableIterator Self; + typedef Open_HashTable HT; + typedef HashNode Node; + + Node *_node; + HT *_pht; + + __HashTableIterator(Node *node, HT *pht) + : _node(node), _pht(pht) + { + } + + T &operator*() + { + return _node->_data; + } + + T *operator->() + { + return &_node->_data; + } + + Self &operator++() + { + if (_node->_next) + { + _node = _node->_next; + } + else + { + // 如果一个桶走完了, 找到下一个桶继续便利 + KeyOfT koft; + size_t index = _pht->HashFunc(koft(_node->_data)) % _pht->_tables.size(); + ++index; + while (index < _pht->_tables.size()) + { + Node *cur = _pht->_tables[index]; + if (cur) + { + _node = cur; + return *this; + } + ++index; + } + _node = nullptr; + } + return *this; + } + + Self operator++(int) + { + Self tmp(*this); + ++*this; + return tmp; + } + + bool operator!=(const Self &s) + { + return _node != s._node; + } + + bool operator==(const Self &s) + { + return _node == s._node; + } + }; + + template + struct _Hash + { + const K &operator()(const K &key) + { + return key; + } + }; + + // 特化 + template <> + struct _Hash + { + size_t operator()(const std::string &key) + { + // BKDR Hash + size_t hash = 0; + for (size_t i = 0; i < key.size(); i++) + { + hash *= 131; + hash += key[i]; + } + return hash; + } + }; + + struct _HashString + { + size_t operator()(const std::string &key) + { + // BKDR Hash + size_t hash = 0; + for (size_t i = 0; i < key.size(); i++) + { + hash *= 131; + hash += key[i]; + } + + return hash; + } + }; + + template + // template > + class Open_HashTable + { + private: + typedef HashNode Node; + + public: + friend struct __HashTableIterator; + typedef __HashTableIterator iterator; + + iterator begin() + { + for (size_t i = 0; i < _tables.size(); i++) + { + if (_tables[i]) + { + return iterator(_tables[i], this); + } + } + return end(); + } + + iterator end() + { + return iterator(nullptr, this); + } + + Open_HashTable() + { + } + + Open_HashTable(size_t bucket_count) + : _tables(bucket_count), _num(0) + { + } + + ~Open_HashTable() + { + Clear(); + } + + void Clear() + { + for (size_t i = 0; i < _tables.size(); i++) + { + Node *cur = _tables[i]; + while (cur) + { + Node *next = cur->_next; + delete cur; + cur = next; + } + _tables[i] = nullptr; + } + } + + size_t HashFunc(const K &key) + { + Hash hash; + return hash(key); + } + + size_t GetNextPrime(size_t num) + { + const int PrimeSize = 28; + static const unsigned long PrimeList[PrimeSize] = + { + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul}; + + for (size_t i = 0; i < PrimeSize; i++) + { + if (PrimeList[i] > num) + { + return PrimeList[i]; + } + } + + return PrimeList[PrimeSize - 1]; // 如果已经是最后一个数的, 则不增容 + } + + // 重新哈希 + void Rehash(size_t newsize) + { + KeyOfT koft; + std::vector newtables; + newtables.resize(newsize); + for (size_t i = 0; i < _tables.size(); i++) + { + // 将旧表中的节点取下来, 重新计算在新表中的位置, 并插入进去 + Node *cur = _tables[i]; + while (cur) + { + Node *next = cur->_next; + size_t index = HashFunc(koft(cur->_data)) % newtables.size(); + cur->_next = newtables[index]; + newtables[index] = cur; + cur = next; + } + _tables[i] = nullptr; + } + _tables.swap(newtables); + } + + // 插入操作 + // 当大量的数据冲突, 这些哈希冲突的数据就会挂在同一个链式桶中, 查找时效率就会降低, 所以开散列-哈希桶也是要控制哈希冲突的。 + // 如何控制呢? 通过控制负载因子, 不过这里就把空间利用率提高一些, 负载因子也可以高一些, 一般开散列把负载因子控制到1, 会比较好一点 + std::pair Insert(const T &data) + { + KeyOfT koft; + + // 1. 检查负载因子 + // 如果负载因子等于 1 , 则增容, 避免大量的哈希冲突 + if (_tables.size() == _num) + { + // 1. 开两倍大小的新表(不一定是两倍) + // 2. 遍历旧表的数据, 重新计算在新表中的位置 + // 3. 释放旧表 + size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // size_t newsize = GetNextPrime(_tables.size()); + + Rehash(newsize); + } + + // 2. 计算数据在表中映射的位置 + size_t index = HashFunc(koft(data)) % _tables.size(); + + // 3. 先查找这个值在不在表中, 是否有冲突 + Node *cur = _tables[index]; + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(koft(data))) + { + // 如果已经存在该键,返回失败 + return std::make_pair(iterator(cur, this), false); + } + else + { + // 查找下一个节点 + cur = cur->_next; + } + } + + // 4. 头插挂到链表中(尾插也是可以的) + Node *newnode = new Node(data); + newnode->_next = _tables[index]; + _tables[index] = newnode; + + ++_num; // 更新已存储元素数量 + return std::make_pair(iterator(newnode, this), true); + } + + // 查找操作 + Node *Find(const K &key) + { + KeyOfT koft; + + // 1. 计算键在表中映射的位置 + size_t index = HashFunc(key) % _tables.size(); + Node *cur = _tables[index]; + + // 2. 遍历链表查找匹配的键 + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(key)) + { + // 如果找到匹配的元素,返回其指针 + return cur; + } + // 继续查找下一个节点 + cur = cur->_next; + } + // 如果未找到,返回空指针 + return nullptr; + } + + bool Erase(const K &key) + { + KeyOfT koft; + + // 1. 计算要删除元素的哈希值 + size_t index = HashFunc(key) % _tables.size(); + Node *prev = nullptr; + Node *cur = _tables[index]; + + // 2. 遍历链表, 查找匹配的元素 + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(key)) + { + // 3. 找到元素后, 调整链表结构 + if (prev == nullptr) + { + // 如果要删除的元素是链表的第一个节点, 直接让桶指向下一个节点 + _tables[index] = cur->_next; + } + else + { + // 否则,将前一个节点的 next 指向当前节点的下一个节点 + prev->_next = cur->_next; + } + // 4. 释放节点内存 + delete cur; + --_num; // 元素数量减少 + return true; + } + else + { + // 继续遍历链表 + prev = cur; + cur = cur->_next; + } + } + // 如果未找到该元素,返回 false + return false; + } + + void Print() const + { + KeyOfT koft; + int size = _tables.size(); + for (int i = 0; i < size; i++) + { + std::cout << i << "\t"; + Node *cur = _tables[i]; + while (cur) + { + std::cout << koft(cur->_data) << "\t"; + cur = cur->_next; + } + std::cout << std::endl; + } + std::cout << std::endl; + } + + private: + std::vector _tables; // 哈希表存储桶 + size_t _num; // 记录着存储的数据个数 + }; +} \ No newline at end of file diff --git a/Linux/Main.cc b/Linux/Main.cc new file mode 100644 index 0000000..851a0fa --- /dev/null +++ b/Linux/Main.cc @@ -0,0 +1,324 @@ +#include "Unordered_Set.hpp" +#include "Unordered_Map.hpp" + +#include +#include +#include +#include +#include +#include + +void Test_unordered_set() +{ + std::unordered_set us; // Java里面取名叫HashSet + us.insert(4); + us.insert(2); + us.insert(1); + std::cout << "us 的 bucket 数量是: " << us.bucket_count() + << "\tus 的 负载因子 是: " << us.load_factor() << std::endl; + us.insert(5); + us.insert(6); + us.insert(3); + us.insert(5); + us.insert(6); + us.insert(3); + us.insert(15); + us.insert(16); + us.insert(13); + std::cout << "us 的 bucket 数量是: " << us.bucket_count() + << "\tus 的 负载因子 是: " << us.load_factor() << std::endl; + us.insert(15); + us.insert(16); + us.insert(13); + us.insert(9); + us.insert(8); + us.insert(10); + us.insert(7); + us.insert(12); + std::cout << "us 的 bucket 数量是: " << us.bucket_count() + << "\tus 的 负载因子 是: " << us.load_factor() << std::endl; + + // 会去重,但是不会自动排序 + std::unordered_set::iterator it = us.begin(); + while (it != us.end()) + { + std::cout << *it << " "; + ++it; + } + std::cout << std::endl; + + std::set s; // Java里面取名叫TreeSet + s.insert(4); + s.insert(2); + s.insert(1); + s.insert(5); + s.insert(6); + s.insert(3); + s.insert(5); + s.insert(6); + s.insert(3); + s.insert(15); + s.insert(16); + s.insert(13); + s.insert(15); + s.insert(16); + s.insert(13); + s.insert(9); + s.insert(8); + s.insert(10); + s.insert(7); + s.insert(12); + // set会去重,会自动排序 + std::set::iterator its = s.begin(); + while (its != s.end()) + { + std::cout << *its << " "; + ++its; + } + std::cout << std::endl; +} + +void Test_unordered_map() +{ + std::unordered_map dict; + dict.insert(std::make_pair("hello", "你好")); + dict.insert(std::make_pair("world", "世界")); + dict.insert(std::make_pair("apple", "苹果")); + dict.insert(std::make_pair("orange", "橘子")); + dict.insert(std::make_pair("banana", "香蕉")); + dict.insert(std::make_pair("peach", "桃子")); + dict.insert(std::make_pair("peach", "桃子")); + dict.insert(std::make_pair("peach", "桃子")); + + dict.insert(std::make_pair("sort", "排序")); + dict["string"] = "字符串"; + + std::unordered_map::iterator it = dict.begin(); + while (it != dict.end()) + { + std::cout << it->first << " " << it->second << std::endl; + ++it; + } + std::cout << std::endl; + + std::map mdict; + mdict.insert(std::make_pair("hello", "你好")); + mdict.insert(std::make_pair("world", "世界")); + mdict.insert(std::make_pair("apple", "苹果")); + mdict.insert(std::make_pair("orange", "橘子")); + mdict.insert(std::make_pair("banana", "香蕉")); + mdict.insert(std::make_pair("peach", "桃子")); + mdict.insert(std::make_pair("peach", "桃子")); + mdict.insert(std::make_pair("peach", "桃子")); + + mdict.insert(std::make_pair("sort", "排序")); + mdict["string"] = "字符串"; + + std::map::iterator mit = mdict.begin(); + while (mit != mdict.end()) + { + std::cout << mit->first << " " << mit->second << std::endl; + ++mit; + } +} + +void Test_OP() +{ + std::unordered_set us; + std::set s; + + const size_t n = 100000; + std::vector v; + v.reserve(n); // reserve()函数是vector预留空间的,但是并不真正创建元素对象。 + // resize()函数是开空间+初始化 + srand(time(0)); + for (size_t i = 0; i < n; ++i) + { + v.push_back(rand()); + } + + // 插入 + clock_t begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.insert(v[i]); + } + clock_t end = clock(); + std::cout << "unordered_set insert time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.insert(v[i]); + } + end = clock(); + std::cout << "set insert time:\t\t" << end - begin << std::endl; + + // 查找 + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.find(v[i]); + } + end = clock(); + std::cout << "unordered_set find time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.find(v[i]); + } + end = clock(); + std::cout << "set find time:\t\t\t" << end - begin << std::endl; + + // 删除 + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.erase(v[i]); + } + end = clock(); + std::cout << "unordered_set erase time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.erase(v[i]); + } + end = clock(); + std::cout << "set erase time:\t\t\t" << end - begin << std::endl; +} + +void Test_Close_HashTable() +{ + Lenyiin::Close_HashTable> ht; + ht.Insert(4); + ht.Insert(14); + ht.Insert(24); + ht.Insert(5); + ht.Insert(15); + ht.Insert(25); + ht.Insert(6); + ht.Insert(16); + + ht.Print(); + + ht.Erase(14); + ht.Erase(24); + ht.Print(); + + std::cout << "是否存在 5 ? " << (ht.Find(5) ? "true" : "false") << std::endl; +} + +void Test_Open_HashTable_1() +{ + Lenyiin::Open_HashTable, Lenyiin::_Hash> ht; + ht.Insert(4); + ht.Insert(14); + ht.Insert(24); + ht.Insert(5); + ht.Insert(15); + ht.Insert(25); + ht.Insert(6); + ht.Insert(16); + ht.Insert(26); + ht.Insert(36); + ht.Insert(33); + ht.Insert(37); + ht.Insert(32); + + ht.Print(); + + ht.Erase(4); + ht.Erase(14); + + ht.Print(); +} + +void Test_Open_HashTable_2() +{ + Lenyiin::Open_HashTable, Lenyiin::_Hash> ht; + ht.Insert("sort"); + ht.Insert("string"); + ht.Insert("left"); + ht.Insert("right"); + + std::cout << ht.HashFunc("abcd") << std::endl; + std::cout << ht.HashFunc("aadd") << std::endl; +} + +void Test_Unordered_Set() +{ + Lenyiin::Unordered_Set s; + s.Insert(1); + s.Insert(5); + s.Insert(4); + s.Insert(2); + s.Insert(5); + s.Insert(5); + s.Insert(53); + s.Insert(54); + + Lenyiin::Unordered_Set::iterator it = s.begin(); + while (it != s.end()) + { + std::cout << *it << " "; + ++it; + } + std::cout << std::endl; + + s.Print(); + + std::cout << "查找 4: " << (s.Find(4) ? "true" : "false") << std::endl; + std::cout << "查找 6: " << (s.Find(6) ? "true" : "false") << std::endl; + + std::cout << "删除 2" << std::endl; + s.Erase(2); + s.Print(); +} + +void Test_Unordered_Map() +{ + Lenyiin::Unordered_Map dict; + dict.Insert(std::make_pair("sort", "排序")); + dict.Insert(std::make_pair("left", "左边")); + dict.Insert(std::make_pair("string", "字符串")); + + dict["left"] = "剩余"; // 修改 + dict["end"] = "尾部"; // 插入 + 修改 + + // Unordered_Map::iterator it = dict.begin(); + auto it = dict.begin(); + while (it != dict.end()) + { + // cout << it->first << ":" << it->second << endl; + std::cout << (*it).first << ":" << (*it).second << std::endl; + ++it; + } + std::cout << std::endl; + + dict.Print(); + + std::cout << "查找 left: " << (dict.Find("left") ? "true" : "false") << std::endl; + std::cout << "查找 up: " << (dict.Find("up") ? "true" : "false") << std::endl; + + std::cout << "删除 left" << std::endl; + dict.Erase("left"); + dict.Print(); +} + +int main() +{ + // Test_unordered_set(); + // Test_unordered_map(); + // Test_OP(); + + // Test_Close_HashTable(); + // Test_Open_HashTable_1(); + // Test_Open_HashTable_2(); + + // Test_Unordered_Set(); + Test_Unordered_Map(); + + return 0; +} \ No newline at end of file diff --git a/Linux/Makefile b/Linux/Makefile new file mode 100644 index 0000000..cd6faa6 --- /dev/null +++ b/Linux/Makefile @@ -0,0 +1,6 @@ +main:Main.cc + g++ -o $@ $^ + +.PHONY:clean +clean: + rm -f main \ No newline at end of file diff --git a/Linux/Unordered_Map.hpp b/Linux/Unordered_Map.hpp new file mode 100644 index 0000000..79a1082 --- /dev/null +++ b/Linux/Unordered_Map.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include "HashTable.hpp" + +namespace Lenyiin +{ + template > + class Unordered_Map + { + public: + struct MapKOfT + { + const K &operator()(const std::pair &kv) + { + return kv.first; + } + }; + + typedef typename Open_HashTable, MapKOfT, Hash>::iterator iterator; + + iterator begin() + { + return _hashTable.begin(); + } + + iterator end() + { + return _hashTable.end(); + } + + // 构造函数: 指定哈希表的初始大小 + Unordered_Map(size_t bucket_count = 10) + : _hashTable(bucket_count) + { + } + + // 析构 + ~Unordered_Map() + { + } + + std::pair Insert(const std::pair &kv) + { + return _hashTable.Insert(kv); + } + + V &operator[](const K &key) + { + std::pair ret = _hashTable.Insert(std::make_pair(key, V())); + return ret.first->second; + } + + // 查找元素 + bool Find(const K &key) + { + return _hashTable.Find(key); + } + + // 删除元素 + bool Erase(const K &key) + { + return _hashTable.Erase(key); + } + + // 打印 + void Print() const + { + _hashTable.Print(); + } + + private: + Open_HashTable, MapKOfT, Hash> _hashTable; + }; +} \ No newline at end of file diff --git a/Linux/Unordered_Set.hpp b/Linux/Unordered_Set.hpp new file mode 100644 index 0000000..caee9c4 --- /dev/null +++ b/Linux/Unordered_Set.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include "HashTable.hpp" + +namespace Lenyiin +{ + template > + class Unordered_Set + { + public: + struct SetKOfT + { + const K &operator()(const K &key) + { + return key; + } + }; + + typedef typename Open_HashTable::iterator iterator; + + iterator begin() + { + return _hashTable.begin(); + } + + iterator end() + { + return _hashTable.end(); + } + + // 构造函数: 指定哈希表的初始大小 + Unordered_Set(size_t bucket_count = 10) + : _hashTable(bucket_count) + { + } + + // 析构 + ~Unordered_Set() + { + } + + // 插入元素 + std::pair Insert(const K &key) + { + return _hashTable.Insert(key); + } + + // 查找元素 + bool Find(const K &key) + { + return _hashTable.Find(key); + } + + // 删除元素 + bool Erase(const K &key) + { + return _hashTable.Erase(key); + } + + // 打印 + void Print() const + { + _hashTable.Print(); + } + + private: + // 使用哈希表作为底层数据结构 + Open_HashTable _hashTable; + }; +} \ No newline at end of file diff --git a/Linux/main b/Linux/main new file mode 100644 index 0000000..bf5c18f Binary files /dev/null and b/Linux/main differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/CodeChunks.db b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/CodeChunks.db new file mode 100644 index 0000000..0b50e9b Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/CodeChunks.db differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db new file mode 100644 index 0000000..21c4a61 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-shm b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-shm new file mode 100644 index 0000000..bcd26bd Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-shm differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-wal b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-wal new file mode 100644 index 0000000..d906370 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/CopilotIndices/0.2.1653.9816/SemanticSymbols.db-wal differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/05f4cc69-6c49-492c-a684-0303168fa925.vsidx b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/05f4cc69-6c49-492c-a684-0303168fa925.vsidx new file mode 100644 index 0000000..9e401e3 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/05f4cc69-6c49-492c-a684-0303168fa925.vsidx differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/07fb3fc6-dd2b-40cf-8655-bdb6a431736e.vsidx b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/07fb3fc6-dd2b-40cf-8655-bdb6a431736e.vsidx new file mode 100644 index 0000000..e422c3a Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/07fb3fc6-dd2b-40cf-8655-bdb6a431736e.vsidx differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/33a41ad7-7b54-4698-ac53-283dd59085eb.vsidx b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/33a41ad7-7b54-4698-ac53-283dd59085eb.vsidx new file mode 100644 index 0000000..5028b74 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/33a41ad7-7b54-4698-ac53-283dd59085eb.vsidx differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/9ebcdc9b-5e56-45da-8de0-0929d1c5b849.vsidx b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/9ebcdc9b-5e56-45da-8de0-0929d1c5b849.vsidx new file mode 100644 index 0000000..eefadc1 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/9ebcdc9b-5e56-45da-8de0-0929d1c5b849.vsidx differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/fde7b025-1a9e-489c-bbe6-dc42e214c8ed.vsidx b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/fde7b025-1a9e-489c-bbe6-dc42e214c8ed.vsidx new file mode 100644 index 0000000..30618ba Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/FileContentIndex/fde7b025-1a9e-489c-bbe6-dc42e214c8ed.vsidx differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/.suo b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/.suo new file mode 100644 index 0000000..498eb02 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/.suo differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/Browse.VC.db b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/Browse.VC.db new file mode 100644 index 0000000..af7d127 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/Browse.VC.db differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.backup.json b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..9fcfb78 --- /dev/null +++ b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.backup.json @@ -0,0 +1,100 @@ +{ + "Version": 1, + "WorkspaceRootPath": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:HashTable.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Unordered_Set.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Unordered_Map.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 267, + "SelectedChildIndex": 3, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:129:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Main.cpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp", + "RelativeDocumentMoniker": "Main.cpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp*", + "RelativeToolTip": "Main.cpp*", + "ViewState": "AgIAACwBAAAAAAAAAAAowDcBAAAZAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-27T15:45:08.801Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "Unordered_Map.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp", + "RelativeDocumentMoniker": "Unordered_Map.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp", + "RelativeToolTip": "Unordered_Map.hpp", + "ViewState": "AgIAACAAAAAAAAAAAAAowEkAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:59.73Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "Unordered_Set.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp", + "RelativeDocumentMoniker": "Unordered_Set.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp", + "RelativeToolTip": "Unordered_Set.hpp", + "ViewState": "AgIAABwAAAAAAAAAAAAowCAAAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:46.521Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "HashTable.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp", + "RelativeDocumentMoniker": "HashTable.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp", + "RelativeToolTip": "HashTable.hpp", + "ViewState": "AgIAAIACAAAAAAAAAAAowKwCAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:25.257Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.json b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.json new file mode 100644 index 0000000..e39843a --- /dev/null +++ b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/DocumentLayout.json @@ -0,0 +1,100 @@ +{ + "Version": 1, + "WorkspaceRootPath": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:HashTable.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Unordered_Set.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}|Windows_Unordered_Set_Map.vcxproj|solutionrelative:Unordered_Map.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 267, + "SelectedChildIndex": 3, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:128:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:129:0:{116d2292-e37d-41cd-a077-ebacac4c8cc4}" + }, + { + "$type": "Bookmark", + "Name": "ST:128:0:{1fc202d4-d401-403c-9834-5b218574bb67}" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Main.cpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp", + "RelativeDocumentMoniker": "Main.cpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Main.cpp", + "RelativeToolTip": "Main.cpp", + "ViewState": "AgIAAPAAAAAAAAAAAAAowP8AAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-27T15:45:08.801Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "Unordered_Map.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp", + "RelativeDocumentMoniker": "Unordered_Map.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Map.hpp", + "RelativeToolTip": "Unordered_Map.hpp", + "ViewState": "AgIAACAAAAAAAAAAAAAowEkAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:59.73Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "Unordered_Set.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp", + "RelativeDocumentMoniker": "Unordered_Set.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\Unordered_Set.hpp", + "RelativeToolTip": "Unordered_Set.hpp", + "ViewState": "AgIAABwAAAAAAAAAAAAowCAAAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:46.521Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "HashTable.hpp", + "DocumentMoniker": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp", + "RelativeDocumentMoniker": "HashTable.hpp", + "ToolTip": "E:\\Git \u4ED3\u5E93\\\u516C\u5F00\u4ED3\u5E93\\10_unordered-set-map\\Windows_Unordered_Set_Map\\HashTable.hpp", + "RelativeToolTip": "HashTable.hpp", + "ViewState": "AgIAAIACAAAAAAAAAAAowKwCAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-27T15:44:25.257Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/10daffe7d69a188a/MAIN.ipch b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/10daffe7d69a188a/MAIN.ipch new file mode 100644 index 0000000..dcd4542 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/10daffe7d69a188a/MAIN.ipch differ diff --git a/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/2dd18e64d50ca78e/HASHTABLE.ipch b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/2dd18e64d50ca78e/HASHTABLE.ipch new file mode 100644 index 0000000..805cb19 Binary files /dev/null and b/Windows_Unordered_Set_Map/.vs/Windows_Unordered_Set_Map/v17/ipch/AutoPCH/2dd18e64d50ca78e/HASHTABLE.ipch differ diff --git a/Windows_Unordered_Set_Map/HashTable.hpp b/Windows_Unordered_Set_Map/HashTable.hpp new file mode 100644 index 0000000..fa550ca --- /dev/null +++ b/Windows_Unordered_Set_Map/HashTable.hpp @@ -0,0 +1,685 @@ +#pragma once + +#include +#include +#include + +// unordered_set -> HashTable +// unordered_map -> HashTable> + +namespace Lenyiin +{ + template + struct SetKeyOfT + { + const K& operator()(const K& key) + { + return key; + } + }; + + enum State + { + EMPTY, // λΪ + EXIST, // λѾһԪ + DELETE // λԪرɾ + }; + + template + struct HashData + { + T _data; + State _state; + + HashData() + : _data(T()), _state(EMPTY) + { + } + }; + + template + class Close_HashTable + { + private: + typedef struct HashData HashData; + + size_t SecondHash(const K& key, size_t table_size) + { + return 1 + (key % (table_size - 1)); + } + + public: + // = /ĴС ϣij̶ + // Խӽ, Խ׳ͻ, ͻԽ, ЧԽ + // ϣ˲, ŶƷ, һ㸺ӵ 0.7 ҾͿʼ + // ԽС, ͻԽ, ЧԽ, ǸԽС, ˷ѵĿռԽ, Ըһȡһеֵ + void CheckCapacity() + { + KeyOfT koft; + + // // version 1 + // if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + // { + // // + // // 1. 2С± + // // 2. ɱݣ¼±λ + // // 3. ͷžɱ + // std::vector newtables; + // size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // newtables.resize(newsize); + // for (size_t i = 0; i < _tables.size(); i++) + // { + // if (_tables[i]._state == EXIST) + // { + // // ±еλ, ͻ + // size_t index = koft(_tables[i]._data) % newtables.size(); + // while (newtables[index]._state == EXIST) + // { + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + // newtables[index] = _tables[i]; + // } + // } + // _tables.swap(newtables); + // } + + // // version 2 + // if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + // { + // // + // // 1. 2С± + // // 2. ɱݣ¼±λ + // // 3. ͷžɱ + // std::vector newtables; + // size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // newtables.resize(newsize); + // for (size_t i = 0; i < _tables.size(); i++) + // { + // if (_tables[i]._state == EXIST) + // { + // // ¼±еλ + // size_t index = koft(_tables[i]._data) % newtables.size(); + // size_t step = SecondHash(koft(_tables[i]._data), newtables.size()); + + // // ͻ˫عϣ̽ + // while (newtables[index]._state == EXIST) + // { + // index = (index + step) % newtables.size(); + // } + + // // Ԫص± + // newtables[index] = _tables[i]; + // } + // } + // _tables.swap(newtables); + // } + + // version 3 + // һ˼· + if (_tables.size() == 0 || _num * 10 / _tables.size() >= 7) + { + Close_HashTable newht; + size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + newht._tables.resize(newsize); + for (size_t i = 0; i < _tables.size(); i++) + { + if (_tables[i]._state == EXIST) + { + newht.Insert(_tables[i]._data); + } + } + _tables.swap(newht._tables); + } + } + + bool Insert(const T& data) + { + KeyOfT koft; + + CheckCapacity(); + // ɢ̽ʲô? + // ̽˼·ҵλñռ, ҾͰȥռ˵λ, ܻᵼһƬһƬijͻ, ˮЧӦ + + // version 1 + // ̽ + // data е key ڱӳλ + // size_t index = koft(data) % _tables.size(); + // while (_tables[index]._state == EXIST) + // { + // if (koft(_tables[index]._data) == koft(data)) + // { + // return false; // Ѿ + // } + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + + // version 2 + // ̽ + // data е key ڱӳλ + // size_t start = koft(data) % _tables.size(); + // size_t index = start; + // int i = 0; + // while (_tables[index]._state == EXIST) + // { + // if (koft(_tables[index]._data) == koft(data)) + // { + // return false; // Ѿ + // } + // index = start + i * i; + // i++; + // index %= _tables.size(); + // } + + // version 3 + // ˫عϣ + size_t index = koft(data) % _tables.size(); + size_t step = SecondHash(koft(data), _tables.size()); + while (_tables[index]._state == EXIST) + { + if (koft(_tables[index]._data) == koft(data)) + { + return false; // ҵͬ keyʧ + } + + index = (index + step) % _tables.size(); // ʹ˫عϣһλ + } + + _tables[index]._data = data; + _tables[index]._state = EXIST; + ++_num; + + // ôԿɢ-ŶƷһֺõĽʽ, Ϊһҵλñռ, Ҿȥռ˵λõ˼· + // Ҳ˵Ĺϣͻ໥Ӱ, ҳͻռ, ͻռ, ͻ... , ûû, Чʶ + // ɢеĹϣͰԽ + return true; + } + + // ̽ + // HashData *Find(const K &key) + // { + // KeyOfT koft; + // // data е key ڱӳλ + // size_t index = key % _tables.size(); + // while (_tables[index]._state != EMPTY) + // { + // if (koft(_tables[index]._data) == key) + // { + // if (_tables[index]._state == EXIST) + // { + // return &_tables[index]; + // } + // else if (_tables[index]._state == DELETE) + // { + // return nullptr; + // } + // } + // ++index; + // if (index == _tables.size()) + // { + // index = 0; + // } + // } + // return nullptr; + // } + + // ˫عϣ + HashData* Find(const K& key) + { + KeyOfT koft; + size_t index = key % _tables.size(); + size_t step = SecondHash(key, _tables.size()); // 㲽 + while (_tables[index]._state != EMPTY) + { + if (koft(_tables[index]._data) == key) + { + if (_tables[index]._state == EXIST) + { + return &_tables[index]; + } + else if (_tables[index]._state == DELETE) + { + return nullptr; + } + } + + index = (index + step) % _tables.size(); // ʹ˫عϣ̽һλ + } + + return nullptr; + } + + bool Erase(const K& key) + { + HashData* ret = Find(key); + if (ret) + { + ret->_state = DELETE; + --_num; + return true; + } + else + { + return false; + } + } + + HashData& getHashData(int pos) + { + return _tables[pos]; + } + + void Print() + { + int size = _tables.size(); + for (int i = 0; i < size; i++) + { + std::cout << i << "\t"; + } + std::cout << std::endl; + + for (int i = 0; i < size; i++) + { + auto cur = _tables[i]; + if (cur._state == EXIST) + { + std::cout << cur._data << "\t"; + } + else + { + std::cout << "*\t"; + } + } + std::cout << "\n\n"; + } + + private: + std::vector _tables; + size_t _num = 0; // 洢˼Ч + }; + + template + struct HashNode + { + T _data; // 洢 + HashNode* _next; // 洢һڵ + + // Ҫʵֵ˳Ϊ˳, Լָһ + // HashNode* _linknext; + // HashNode* _linkprev; + + HashNode(const T& data) + : _data(data), _next(nullptr) + { + } + }; + + // ǰ + template + class Open_HashTable; + + // ϣֻе, ֻ ++, û-- + template + struct __HashTableIterator + { + typedef __HashTableIterator Self; + typedef Open_HashTable HT; + typedef HashNode Node; + + Node* _node; + HT* _pht; + + __HashTableIterator(Node* node, HT* pht) + : _node(node), _pht(pht) + { + } + + T& operator*() + { + return _node->_data; + } + + T* operator->() + { + return &_node->_data; + } + + Self& operator++() + { + if (_node->_next) + { + _node = _node->_next; + } + else + { + // һͰ, ҵһͰ + KeyOfT koft; + size_t index = _pht->HashFunc(koft(_node->_data)) % _pht->_tables.size(); + ++index; + while (index < _pht->_tables.size()) + { + Node* cur = _pht->_tables[index]; + if (cur) + { + _node = cur; + return *this; + } + ++index; + } + _node = nullptr; + } + return *this; + } + + Self operator++(int) + { + Self tmp(*this); + ++*this; + return tmp; + } + + bool operator!=(const Self& s) + { + return _node != s._node; + } + + bool operator==(const Self& s) + { + return _node == s._node; + } + }; + + template + struct _Hash + { + const K& operator()(const K& key) + { + return key; + } + }; + + // ػ + template <> + struct _Hash + { + size_t operator()(const std::string& key) + { + // BKDR Hash + size_t hash = 0; + for (size_t i = 0; i < key.size(); i++) + { + hash *= 131; + hash += key[i]; + } + return hash; + } + }; + + struct _HashString + { + size_t operator()(const std::string& key) + { + // BKDR Hash + size_t hash = 0; + for (size_t i = 0; i < key.size(); i++) + { + hash *= 131; + hash += key[i]; + } + + return hash; + } + }; + + template + // template > + class Open_HashTable + { + private: + typedef HashNode Node; + + public: + friend struct __HashTableIterator; + typedef __HashTableIterator iterator; + + iterator begin() + { + for (size_t i = 0; i < _tables.size(); i++) + { + if (_tables[i]) + { + return iterator(_tables[i], this); + } + } + return end(); + } + + iterator end() + { + return iterator(nullptr, this); + } + + Open_HashTable() + { + } + + Open_HashTable(size_t bucket_count) + : _tables(bucket_count), _num(0) + { + } + + ~Open_HashTable() + { + Clear(); + } + + void Clear() + { + for (size_t i = 0; i < _tables.size(); i++) + { + Node* cur = _tables[i]; + while (cur) + { + Node* next = cur->_next; + delete cur; + cur = next; + } + _tables[i] = nullptr; + } + } + + size_t HashFunc(const K& key) + { + Hash hash; + return hash(key); + } + + size_t GetNextPrime(size_t num) + { + const int PrimeSize = 28; + static const unsigned long PrimeList[PrimeSize] = + { + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul }; + + for (size_t i = 0; i < PrimeSize; i++) + { + if (PrimeList[i] > num) + { + return PrimeList[i]; + } + } + + return PrimeList[PrimeSize - 1]; // Ѿһ, + } + + // ¹ϣ + void Rehash(size_t newsize) + { + KeyOfT koft; + std::vector newtables; + newtables.resize(newsize); + for (size_t i = 0; i < _tables.size(); i++) + { + // ɱеĽڵȡ, ¼±еλ, ȥ + Node* cur = _tables[i]; + while (cur) + { + Node* next = cur->_next; + size_t index = HashFunc(koft(cur->_data)) % newtables.size(); + cur->_next = newtables[index]; + newtables[index] = cur; + cur = next; + } + _tables[i] = nullptr; + } + _tables.swap(newtables); + } + + // + // ݳͻ, ЩϣͻݾͻͬһʽͰ, ʱЧʾͻή, Կɢ-ϣͰҲҪƹϣͻġ + // ο? ͨƸ, ͰѿռһЩ, ҲԸһЩ, һ㿪ɢаѸӿƵ1, ȽϺһ + std::pair Insert(const T& data) + { + KeyOfT koft; + + // 1. 鸺 + // ӵ 1 , , Ĺϣͻ + if (_tables.size() == _num) + { + // 1. С±һ + // 2. ɱ, ¼±еλ + // 3. ͷžɱ + size_t newsize = _tables.size() == 0 ? 10 : _tables.size() * 2; + // size_t newsize = GetNextPrime(_tables.size()); + + Rehash(newsize); + } + + // 2. ڱӳλ + size_t index = HashFunc(koft(data)) % _tables.size(); + + // 3. Ȳֵڲڱ, Ƿгͻ + Node* cur = _tables[index]; + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(koft(data))) + { + // Ѿڸüʧ + return std::make_pair(iterator(cur, this), false); + } + else + { + // һڵ + cur = cur->_next; + } + } + + // 4. ͷҵ(βҲǿԵ) + Node* newnode = new Node(data); + newnode->_next = _tables[index]; + _tables[index] = newnode; + + ++_num; // Ѵ洢Ԫ + return std::make_pair(iterator(newnode, this), true); + } + + // Ҳ + Node* Find(const K& key) + { + KeyOfT koft; + + // 1. ڱӳλ + size_t index = HashFunc(key) % _tables.size(); + Node* cur = _tables[index]; + + // 2. ƥļ + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(key)) + { + // ҵƥԪأָ + return cur; + } + // һڵ + cur = cur->_next; + } + // δҵؿָ + return nullptr; + } + + bool Erase(const K& key) + { + KeyOfT koft; + + // 1. ҪɾԪصĹϣֵ + size_t index = HashFunc(key) % _tables.size(); + Node* prev = nullptr; + Node* cur = _tables[index]; + + // 2. , ƥԪ + while (cur) + { + if (HashFunc(koft(cur->_data)) == HashFunc(key)) + { + // 3. ҵԪغ, ṹ + if (prev == nullptr) + { + // ҪɾԪĵһڵ, ֱͰָһڵ + _tables[index] = cur->_next; + } + else + { + // 򣬽ǰһڵ next ָǰڵһڵ + prev->_next = cur->_next; + } + // 4. ͷŽڵڴ + delete cur; + --_num; // Ԫ + return true; + } + else + { + // + prev = cur; + cur = cur->_next; + } + } + // δҵԪأ false + return false; + } + + void Print() const + { + KeyOfT koft; + int size = _tables.size(); + for (int i = 0; i < size; i++) + { + std::cout << i << "\t"; + Node* cur = _tables[i]; + while (cur) + { + std::cout << koft(cur->_data) << "\t"; + cur = cur->_next; + } + std::cout << std::endl; + } + std::cout << std::endl; + } + + private: + std::vector _tables; // ϣ洢Ͱ + size_t _num; // ¼Ŵ洢ݸ + }; +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Main.cpp b/Windows_Unordered_Set_Map/Main.cpp new file mode 100644 index 0000000..19a2f50 --- /dev/null +++ b/Windows_Unordered_Set_Map/Main.cpp @@ -0,0 +1,324 @@ +#include "Unordered_Set.hpp" +#include "Unordered_Map.hpp" + +#include +#include +#include +#include +#include +#include + +void Test_unordered_set() +{ + std::unordered_set us; // JavaȡHashSet + us.insert(4); + us.insert(2); + us.insert(1); + std::cout << "us bucket : " << us.bucket_count() + << "\tus : " << us.load_factor() << std::endl; + us.insert(5); + us.insert(6); + us.insert(3); + us.insert(5); + us.insert(6); + us.insert(3); + us.insert(15); + us.insert(16); + us.insert(13); + std::cout << "us bucket : " << us.bucket_count() + << "\tus : " << us.load_factor() << std::endl; + us.insert(15); + us.insert(16); + us.insert(13); + us.insert(9); + us.insert(8); + us.insert(10); + us.insert(7); + us.insert(12); + std::cout << "us bucket : " << us.bucket_count() + << "\tus : " << us.load_factor() << std::endl; + + // ȥأDzԶ + std::unordered_set::iterator it = us.begin(); + while (it != us.end()) + { + std::cout << *it << " "; + ++it; + } + std::cout << std::endl; + + std::set s; // JavaȡTreeSet + s.insert(4); + s.insert(2); + s.insert(1); + s.insert(5); + s.insert(6); + s.insert(3); + s.insert(5); + s.insert(6); + s.insert(3); + s.insert(15); + s.insert(16); + s.insert(13); + s.insert(15); + s.insert(16); + s.insert(13); + s.insert(9); + s.insert(8); + s.insert(10); + s.insert(7); + s.insert(12); + // setȥأԶ + std::set::iterator its = s.begin(); + while (its != s.end()) + { + std::cout << *its << " "; + ++its; + } + std::cout << std::endl; +} + +void Test_unordered_map() +{ + std::unordered_map dict; + dict.insert(std::make_pair("hello", "")); + dict.insert(std::make_pair("world", "")); + dict.insert(std::make_pair("apple", "ƻ")); + dict.insert(std::make_pair("orange", "")); + dict.insert(std::make_pair("banana", "㽶")); + dict.insert(std::make_pair("peach", "")); + dict.insert(std::make_pair("peach", "")); + dict.insert(std::make_pair("peach", "")); + + dict.insert(std::make_pair("sort", "")); + dict["string"] = "ַ"; + + std::unordered_map::iterator it = dict.begin(); + while (it != dict.end()) + { + std::cout << it->first << " " << it->second << std::endl; + ++it; + } + std::cout << std::endl; + + std::map mdict; + mdict.insert(std::make_pair("hello", "")); + mdict.insert(std::make_pair("world", "")); + mdict.insert(std::make_pair("apple", "ƻ")); + mdict.insert(std::make_pair("orange", "")); + mdict.insert(std::make_pair("banana", "㽶")); + mdict.insert(std::make_pair("peach", "")); + mdict.insert(std::make_pair("peach", "")); + mdict.insert(std::make_pair("peach", "")); + + mdict.insert(std::make_pair("sort", "")); + mdict["string"] = "ַ"; + + std::map::iterator mit = mdict.begin(); + while (mit != mdict.end()) + { + std::cout << mit->first << " " << mit->second << std::endl; + ++mit; + } +} + +void Test_OP() +{ + std::unordered_set us; + std::set s; + + const size_t n = 100000; + std::vector v; + v.reserve(n); // reserve()vectorԤռģDzԪض + // resize()ǿռ+ʼ + srand(time(0)); + for (size_t i = 0; i < n; ++i) + { + v.push_back(rand()); + } + + // + clock_t begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.insert(v[i]); + } + clock_t end = clock(); + std::cout << "unordered_set insert time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.insert(v[i]); + } + end = clock(); + std::cout << "set insert time:\t\t" << end - begin << std::endl; + + // + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.find(v[i]); + } + end = clock(); + std::cout << "unordered_set find time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.find(v[i]); + } + end = clock(); + std::cout << "set find time:\t\t\t" << end - begin << std::endl; + + // ɾ + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + us.erase(v[i]); + } + end = clock(); + std::cout << "unordered_set erase time:\t" << end - begin << std::endl; + + begin = clock(); + for (size_t i = 0; i < n; ++i) + { + s.erase(v[i]); + } + end = clock(); + std::cout << "set erase time:\t\t\t" << end - begin << std::endl; +} + +void Test_Close_HashTable() +{ + Lenyiin::Close_HashTable> ht; + ht.Insert(4); + ht.Insert(14); + ht.Insert(24); + ht.Insert(5); + ht.Insert(15); + ht.Insert(25); + ht.Insert(6); + ht.Insert(16); + + ht.Print(); + + ht.Erase(14); + ht.Erase(24); + ht.Print(); + + std::cout << "Ƿ 5 ? " << (ht.Find(5) ? "true" : "false") << std::endl; +} + +void Test_Open_HashTable_1() +{ + Lenyiin::Open_HashTable, Lenyiin::_Hash> ht; + ht.Insert(4); + ht.Insert(14); + ht.Insert(24); + ht.Insert(5); + ht.Insert(15); + ht.Insert(25); + ht.Insert(6); + ht.Insert(16); + ht.Insert(26); + ht.Insert(36); + ht.Insert(33); + ht.Insert(37); + ht.Insert(32); + + ht.Print(); + + ht.Erase(4); + ht.Erase(14); + + ht.Print(); +} + +void Test_Open_HashTable_2() +{ + Lenyiin::Open_HashTable, Lenyiin::_Hash> ht; + ht.Insert("sort"); + ht.Insert("string"); + ht.Insert("left"); + ht.Insert("right"); + + std::cout << ht.HashFunc("abcd") << std::endl; + std::cout << ht.HashFunc("aadd") << std::endl; +} + +void Test_Unordered_Set() +{ + Lenyiin::Unordered_Set s; + s.Insert(1); + s.Insert(5); + s.Insert(4); + s.Insert(2); + s.Insert(5); + s.Insert(5); + s.Insert(53); + s.Insert(54); + + Lenyiin::Unordered_Set::iterator it = s.begin(); + while (it != s.end()) + { + std::cout << *it << " "; + ++it; + } + std::cout << std::endl; + + s.Print(); + + std::cout << " 4: " << (s.Find(4) ? "true" : "false") << std::endl; + std::cout << " 6: " << (s.Find(6) ? "true" : "false") << std::endl; + + std::cout << "ɾ 2" << std::endl; + s.Erase(2); + s.Print(); +} + +void Test_Unordered_Map() +{ + Lenyiin::Unordered_Map dict; + dict.Insert(std::make_pair("sort", "")); + dict.Insert(std::make_pair("left", "")); + dict.Insert(std::make_pair("string", "ַ")); + + dict["left"] = "ʣ"; // ޸ + dict["end"] = "β"; // + ޸ + + // Unordered_Map::iterator it = dict.begin(); + auto it = dict.begin(); + while (it != dict.end()) + { + // cout << it->first << ":" << it->second << endl; + std::cout << (*it).first << ":" << (*it).second << std::endl; + ++it; + } + std::cout << std::endl; + + dict.Print(); + + std::cout << " left: " << (dict.Find("left") ? "true" : "false") << std::endl; + std::cout << " up: " << (dict.Find("up") ? "true" : "false") << std::endl; + + std::cout << "ɾ left" << std::endl; + dict.Erase("left"); + dict.Print(); +} + +int main() +{ + Test_unordered_set(); + Test_unordered_map(); + Test_OP(); + + Test_Close_HashTable(); + Test_Open_HashTable_1(); + Test_Open_HashTable_2(); + + Test_Unordered_Set(); + Test_Unordered_Map(); + + return 0; +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Unordered_Map.hpp b/Windows_Unordered_Set_Map/Unordered_Map.hpp new file mode 100644 index 0000000..331aa12 --- /dev/null +++ b/Windows_Unordered_Set_Map/Unordered_Map.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include "HashTable.hpp" + +namespace Lenyiin +{ + template > + class Unordered_Map + { + public: + struct MapKOfT + { + const K& operator()(const std::pair& kv) + { + return kv.first; + } + }; + + typedef typename Open_HashTable, MapKOfT, Hash>::iterator iterator; + + iterator begin() + { + return _hashTable.begin(); + } + + iterator end() + { + return _hashTable.end(); + } + + // 캯: ָϣijʼС + Unordered_Map(size_t bucket_count = 10) + : _hashTable(bucket_count) + { + } + + // + ~Unordered_Map() + { + } + + std::pair Insert(const std::pair& kv) + { + return _hashTable.Insert(kv); + } + + V& operator[](const K& key) + { + std::pair ret = _hashTable.Insert(std::make_pair(key, V())); + return ret.first->second; + } + + // Ԫ + bool Find(const K& key) + { + return _hashTable.Find(key); + } + + // ɾԪ + bool Erase(const K& key) + { + return _hashTable.Erase(key); + } + + // ӡ + void Print() const + { + _hashTable.Print(); + } + + private: + Open_HashTable, MapKOfT, Hash> _hashTable; + }; +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Unordered_Set.hpp b/Windows_Unordered_Set_Map/Unordered_Set.hpp new file mode 100644 index 0000000..bb73600 --- /dev/null +++ b/Windows_Unordered_Set_Map/Unordered_Set.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include "HashTable.hpp" + +namespace Lenyiin +{ + template > + class Unordered_Set + { + public: + struct SetKOfT + { + const K& operator()(const K& key) + { + return key; + } + }; + + typedef typename Open_HashTable::iterator iterator; + + iterator begin() + { + return _hashTable.begin(); + } + + iterator end() + { + return _hashTable.end(); + } + + // 캯: ָϣijʼС + Unordered_Set(size_t bucket_count = 10) + : _hashTable(bucket_count) + { + } + + // + ~Unordered_Set() + { + } + + // Ԫ + std::pair Insert(const K& key) + { + return _hashTable.Insert(key); + } + + // Ԫ + bool Find(const K& key) + { + return _hashTable.Find(key); + } + + // ɾԪ + bool Erase(const K& key) + { + return _hashTable.Erase(key); + } + + // ӡ + void Print() const + { + _hashTable.Print(); + } + + private: + // ʹùϣΪײݽṹ + Open_HashTable _hashTable; + }; +} \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Main.obj b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Main.obj new file mode 100644 index 0000000..b2433ae Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Main.obj differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.command.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.command.1.tlog new file mode 100644 index 0000000..f42645f Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.command.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.read.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.read.1.tlog new file mode 100644 index 0000000..305a16b Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.read.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.write.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.write.1.tlog new file mode 100644 index 0000000..a51b8cc Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/CL.write.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Cl.items.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Cl.items.tlog new file mode 100644 index 0000000..71d6e1a --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Cl.items.tlog @@ -0,0 +1 @@ +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp;E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Windows_.6c808d8b\x64\Debug\Main.obj diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Windows_Unordered_Set_Map.lastbuildstate b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Windows_Unordered_Set_Map.lastbuildstate new file mode 100644 index 0000000..9005e42 --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/Windows_Unordered_Set_Map.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.41.34120:TargetPlatformVersion=10.0.22000.0: +Debug|x64|E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\| diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.command.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.command.1.tlog new file mode 100644 index 0000000..5c48ab1 Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.command.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.read.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.read.1.tlog new file mode 100644 index 0000000..976dda0 Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.read.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.secondary.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.secondary.1.tlog new file mode 100644 index 0000000..b83a95c --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.secondary.1.tlog @@ -0,0 +1,2 @@ +^E:\GIT 仓库\公开仓库\10_UNORDERED-SET-MAP\WINDOWS_UNORDERED_SET_MAP\WINDOWS_.6C808D8B\X64\DEBUG\MAIN.OBJ +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Windows_.6c808d8b\x64\Debug\Windows_Unordered_Set_Map.ilk diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.write.1.tlog b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.write.1.tlog new file mode 100644 index 0000000..03a86f4 Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_.6c808d8b.tlog/link.write.1.tlog differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.exe.recipe b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.exe.recipe new file mode 100644 index 0000000..e462c3d --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.exe.recipe @@ -0,0 +1,11 @@ + + + + + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\x64\Debug\Windows_Unordered_Set_Map.exe + + + + + + \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.ilk b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.ilk new file mode 100644 index 0000000..9cdcdce Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.ilk differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.log b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.log new file mode 100644 index 0000000..5965dd2 --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/Windows_Unordered_Set_Map.log @@ -0,0 +1,38 @@ + Main.cpp +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(134,15): warning C4244: “参数”: 从“time_t”转换到“unsigned int”,可能丢失数据 +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(161,12): warning C4834: 放弃具有 [[nodiscard]] 属性的函数的返回值 +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(169,11): warning C4834: 放弃具有 [[nodiscard]] 属性的函数的返回值 +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(666,22): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 + (编译源文件“Main.cpp”) + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(666,22): + 模板实例化上下文(最早的实例化上下文)为 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(215,85): + 查看对正在编译的 类 模板 实例化“Lenyiin::Open_HashTable,Lenyiin::_Hash>”的引用 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(663,14): + 在编译 类 模板 成员函数“void Lenyiin::Open_HashTable,Lenyiin::_Hash>::Print(void) const”时 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(230,13): + 请参阅 "Test_Open_HashTable_1" 中对 "Lenyiin::Open_HashTable,Lenyiin::_Hash>::Print" 的第一个引用 + +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(281,22): warning C4267: “初始化”: 从“size_t”转换到“int”,可能丢失数据 + (编译源文件“Main.cpp”) + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(281,22): + 模板实例化上下文(最早的实例化上下文)为 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(194,65): + 查看对正在编译的 类 模板 实例化“Lenyiin::Close_HashTable>”的引用 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(279,14): + 在编译 类 模板 成员函数“void Lenyiin::Close_HashTable>::Print(void)”时 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(204,13): + 请参阅 "Test_Close_HashTable" 中对 "Lenyiin::Close_HashTable>::Print" 的第一个引用 + +E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(58,20): warning C4101: “koft”: 未引用的局部变量 + (编译源文件“Main.cpp”) + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(58,20): + 模板实例化上下文(最早的实例化上下文)为 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(56,14): + 在编译 类 模板 成员函数“void Lenyiin::Close_HashTable>::CheckCapacity(void)”时 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\HashTable.hpp(143,26): + 请参阅 "Lenyiin::Close_HashTable>::Insert" 中对 "Lenyiin::Close_HashTable>::CheckCapacity" 的第一个引用 + E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\Main.cpp(195,14): + 请参阅 "Test_Close_HashTable" 中对 "Lenyiin::Close_HashTable>::Insert" 的第一个引用 + + Windows_Unordered_Set_Map.vcxproj -> E:\Git 仓库\公开仓库\10_unordered-set-map\Windows_Unordered_Set_Map\x64\Debug\Windows_Unordered_Set_Map.exe diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.idb b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.idb new file mode 100644 index 0000000..1a7c712 Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.idb differ diff --git a/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.pdb b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.pdb new file mode 100644 index 0000000..3fcbefd Binary files /dev/null and b/Windows_Unordered_Set_Map/Windows_.6c808d8b/x64/Debug/vc143.pdb differ diff --git a/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.sln b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.sln new file mode 100644 index 0000000..49c4b96 --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Windows_Unordered_Set_Map", "Windows_Unordered_Set_Map.vcxproj", "{6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Debug|x64.ActiveCfg = Debug|x64 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Debug|x64.Build.0 = Debug|x64 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Debug|x86.ActiveCfg = Debug|Win32 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Debug|x86.Build.0 = Debug|Win32 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Release|x64.ActiveCfg = Release|x64 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Release|x64.Build.0 = Release|x64 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Release|x86.ActiveCfg = Release|Win32 + {6C808D8B-0CB3-42B6-AF2E-ED6384CC59B8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CDBD2AFD-9BDF-4941-A594-4E0BFAA55F03} + EndGlobalSection +EndGlobal diff --git a/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj new file mode 100644 index 0000000..c05febb --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {6c808d8b-0cb3-42b6-af2e-ed6384cc59b8} + WindowsUnorderedSetMap + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.filters b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.filters new file mode 100644 index 0000000..19042a0 --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + 头文件 + + + 头文件 + + + + + 源文件 + + + \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.user b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Windows_Unordered_Set_Map/Windows_Unordered_Set_Map.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.exe b/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.exe new file mode 100644 index 0000000..482ab4c Binary files /dev/null and b/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.exe differ diff --git a/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.pdb b/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.pdb new file mode 100644 index 0000000..e4e70f1 Binary files /dev/null and b/Windows_Unordered_Set_Map/x64/Debug/Windows_Unordered_Set_Map.pdb differ