wordpress子站点装修黑榜第一名

张小明 2025/12/31 20:25:58
wordpress子站点,装修黑榜第一名,微信公用号 wordpress,wordpress移动端导航菜单1. 哈希概念 哈希(hash)又称散列#xff0c;是⼀种组织数据的方式。从译名来看#xff0c;有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建立⼀个映射关系#xff0c;查找时通过这个哈希函数计算出Key存储的位置#xff0c;进行快速查找。 1.1 直接定址法…1. 哈希概念哈希(hash)又称散列是⼀种组织数据的方式。从译名来看有散乱排列的意思。本质就是通过哈希函数把关键字Key跟存储位置建立⼀个映射关系查找时通过这个哈希函数计算出Key存储的位置进行快速查找。1.1 直接定址法当关键字的范围比较集中时直接定址法就是⾮常简单高效的⽅法⽐如⼀组关键字都在[0,99]之间那么我们开⼀个100个数的数组每个关键字的值直接就是存储位置的下标。再⽐如⼀组关键字值都在[a,z]的小写字母那么我们开⼀个26个数的数组每个关键字acsii码-a ascii码就是存储位置的下标。也就是说直接定址法本质就是⽤关键字计算出⼀个绝对位置或者相对位置。这个方法我们在计数排序部分已经用过了其次在string章节的下面OJ也用过了。leetcode链接387. 字符串中的第一个唯一字符 - 力扣LeetCodeclass Solution { public: int firstUniqChar(string s) { int hash[26] {0}; for(auto e : s) { hash[ e -a]; } for(size_t i 0; i s.size(); i) { if(hash[s[i] - a] 1) return i; } return -1; } };1.2 哈希冲突直接定址法的缺点也非常明显当关键字的范围⽐较分散时就很浪费内存甚⾄内存不够⽤。假设我们只有数据范围是[0, 9999]的N个值我们要映射到⼀个M个空间的数组中(⼀般情况下M N)那么就要借助哈希函数(hash function)hf关键字key被放到数组的h(key)位置这⾥要注意的是h(key)计算出的值必须在[0, M)之间。这⾥存在的⼀个问题就是两个不同的key可能会映射到同⼀个位置去这种问题我们叫做哈希冲突或者哈希碰撞。理想情况是找出⼀个好的哈希函数避免冲突但是实际场景中冲突是不可避免的所以我们尽可能设计出优秀的哈希函数减少冲突的次数同时也要去设计出解决冲突的⽅案。1.3 负载因子假设哈希表中已经映射存储了N个值哈希表的大小为M那么负载因子N/M负载因子有些地方也翻译为载荷因子/装载因子等他的英⽂为load factor。负载因子越大哈希冲突的概率越⾼空间利⽤率越⾼负载因子越小哈希冲突的概率越低空间利用率越低1.4 将关键字转为整数我们将关键字映射到数组中位置⼀般是整数好做映射计算如果不是整数我们要想办法转换成整数这个细节我们后面代码实现中再进行细节展示。下面哈希函数部分我们讨论时如果关键字不是整数那么我们讨论的Key是关键字转换成的整数。1.5 哈希函数⼀个好的哈希函数应该让N个关键字被等概率的均匀的散列分布到哈希表的M个空间中但是实际中却很难做到但是我们要尽量往这个方向去考量设计。1.5.1 除法散列法/除留余数法1.5.2 乘法散列法了解1.5.3 全域散列法了解1.5.4 其他方法了解1.6 处理哈希冲突实践中哈希表⼀般还是选择除法散列法作为哈希函数当然哈希表⽆论选择什么哈希函数也避免不了冲突那么插⼊数据时如何解决冲突呢主要有两种⽅法开放定址法和链地址法。1.6.1 开放定址法在开放定址法中所有的元素都放到哈希表⾥当⼀个关键字key⽤哈希函数计算出的位置冲突了则按照某种规则找到⼀个没有存储数据的位置进⾏存储开放定址法中负载因⼦⼀定是小于的。这⾥的规则有三种线性探测、⼆次探测、双重探测。线性探测二次探测双重散列了解1.6.2 开放定址法代码实现开放定址法在实践中不如下⾯讲的链地址法因为开放定址法解决冲突不管使用哪种⽅法占用的都是哈希表中的空间始终存在互相影响的问题。所以开放定址法我们简单选择线性探测实现即可。开放定址法的哈希表结构enum State { EXIST, EMPTY, DELETE }; templateclass K, class V struct HashData { pairK, V _kv; State _state EMPTY; }; templateclass K, class V class HashTable { private: vectorHashDataK, V _tables; size_t _n 0; // 表中存储数据个数 };要注意的是这⾥需要给每个存储值的位置加⼀个状态标识否则删除⼀些值以后会影响后面冲突的值的查找。如下图我们删除30会导致查找20失败当我们给每个位置加⼀个状态标识{EXIST,EMPTY,DELETE}删除30就可以不用删除值⽽是把状态改为 DELETE 那么查找20时是遇到 EMPTY 才能就可以找到20。扩容这⾥我们哈希表负载因子控制在0.7当负载因子到0.7以后我们就需要扩容了我们还是按照2倍扩容但是同时我们要保持哈希表大小是⼀个质数第⼀个是质数2倍后就不是质数了。那么如何解决了⼀种方案就是上⾯1.4.1除法散列中我们讲的Java HashMap的使⽤2的整数幂但是计算时不能直接取模的改进⽅法。另外⼀种⽅案是sgi版本的哈希表使⽤的⽅法给了⼀个近似2倍的质数表每次去质数表获取扩容后的大小。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 }; inline unsigned long __stl_next_prime(unsigned long n) { const unsigned long* first __stl_prime_list; const unsigned long* last __stl_prime_list __stl_num_primes; // n const unsigned long* pos lower_bound(first, last, n); return pos last ? *(last - 1) : *pos; }key不能取模的问题当key是string/Date等类型时key不能取模那么我们需要给HashTable增加⼀个仿函数这个仿函数⽀持把key转换成⼀个可以取模的整形如果key可以转换为整形并且不容易冲突那么这个仿函数就⽤默认参数即可如果这个Key不能转换为整形我们就需要自己实现⼀个仿函数传给这个参数实现这个仿函数的要求就是尽量key的每值都参与到计算中让不同的key转换出的整形值不同。string做哈希表的key⾮常常见所以我们可以考虑把string特化⼀下。templateclass K struct HashFunc { size_t operator()(const K key) { return (size_t)key; } }; template //特化 struct HashFuncstring { /* 字符串转换成整形可以把字符ascii码相加即可 但是直接相加的话类似abcd和bcad这样的字符串计算出是相同的 这⾥我们使⽤BKDR哈希的思路用上次的计算结果去乘以⼀个质数这个质数⼀般取31131 等效果会比较好*/ size_t operator()(const string key) { // abcd size_t hash 0; for (auto e : key) { hash hash * 131; hash e; } return hash; } }; enum State { EXIST, EMPTY, DELETE }; templateclass K, class V struct HashData { pairK, V _kv; State _state EMPTY; }; templateclass K, class V, class Hash HashFuncK class HashTable { private: vectorHashDataK, V _tables; size_t _n 0; // 表中存储数据个数 };完整代码实现#pragma once #includevector #includestring using namespace std; 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 }; inline unsigned long __stl_next_prime(unsigned long n) { const unsigned long* first __stl_prime_list; const unsigned long* last __stl_prime_list __stl_num_primes; // n const unsigned long* pos lower_bound(first, last, n); return pos last ? *(last - 1) : *pos; } templateclass K struct HashFunc { size_t operator()(const K key) { return (size_t)key; } }; //特化 template struct HashFuncstring { /* 字符串转换成整形可以把字符ascii码相加即可 但是直接相加的话类似abcd和bcad这样的字符串计算出是相同的 这⾥我们使⽤BKDR哈希的思路用上次的计算结果去乘以⼀个质数这个质数⼀般取31131 等效果会比较好*/ size_t operator()(const string key) { // abcd size_t hash 0; for (auto e : key) { hash hash e; hash hash * 131; } return hash; } }; enum State { EXIST, EMPTY, DELETE }; templateclass K, class V struct HashData { pairK, V _kv; State _state EMPTY; }; templateclass K, class V, class Hash HashFuncK class HashTable { public: HashTable() :_tables(__stl_next_prime(1)) {} bool Insert(const pairK, V kv) { if (Find(kv.first)) { return false; } // 负载因子 0.7 就扩容 if ((double)_n / (double)_tables.size() 0.7) { //std::vectorHashData newtables(_tables.size()*2); //for (size_t i 0; i _tables.size(); i) //{ // if (_tables[i]._state EXIST) // { // // 重新映射到新表 // // ... // } //} //_tables.swap(newtables); HashTableK, V, Hash newht; newht._tables.resize(__stl_next_prime(_tables.size() 1)); for (size_t i 0; i _tables.size(); i) { // 遍历旧表旧表数据插入到newht中 if (_tables[i]._state EXIST) { newht.Insert(_tables[i]._kv); } } _tables.swap(newht._tables); } Hash hs; size_t hash0 hs(kv.first) % _tables.size(); // 线性探测 size_t hashi hash0; size_t i 1; while (_tables[hashi]._state EXIST) { hashi (hashi i) % _tables.size(); i; } _tables[hashi]._kv kv; _tables[hashi]._state EXIST; _n; return true; } // 查找 HashDataK, V* Find(const K key) { Hash hs; size_t hash0 hs(key) % _tables.size(); // 线性探测 size_t hashi hash0; size_t i 1; while (_tables[hashi]._state ! EMPTY) { if (_tables[hashi]._state ! DELETE _tables[hashi]._kv.first key) { return _tables[hashi]; } hashi (hash0 i) % _tables.size(); i; } return nullptr; } // 删除 bool Erase(const K key) { HashDataK, V* ret Find(key); if (ret) { ret-_state DELETE; --_n; return true; } else { return false; } } private: vectorHashDataK, V _tables; size_t _n 0; // 表中存储数据个数 };
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

广州建设网站制作网站建设公司普遍存在劣势

TV Bro:重新定义电视端网页浏览体验的智能浏览器 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro 在智能电视日益普及的今天,客厅大屏已成为家庭娱…

张小明 2025/12/31 18:03:57 网站建设

网站如何paypal支付wordpress 免插件实现

本文详解PEFT参数高效微调技术及其分类,重点解析LoRA(低秩适配)的核心原理与实现。LoRA通过将权重矩阵低秩分解为两个小矩阵,仅训练少量参数,显著降低显存占用和训练时间。结合QLoRA量化技术,进一步优化资源…

张小明 2025/12/30 12:13:49 网站建设

网站 报价单关键词优化策略

网盘直链下载助手使用教程:轻松获取真实下载地址的完整指南 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改(改自6.1.4版本) ,自用,去推广…

张小明 2025/12/30 12:12:30 网站建设

做母婴的网站怎么做线上推广

百度AI社区热议Qwen-Image-Edit-2509实际应用效果 最近在百度AI社区,一个名为 Qwen-Image-Edit-2509 的模型镜像引发了广泛讨论。不少开发者和内容创作者都在试用后反馈:“这可能是目前最接近‘所想即改’理想的图像编辑AI。” 它不再依赖复杂的图层操作…

张小明 2025/12/30 12:11:15 网站建设

如何变更网站备案信息查询滁州市建设银行网站

在学术论文撰写过程中,高效完成开题报告与正文内容对学生构成显著挑战。传统人工写作模式虽具备灵活性,但存在效率瓶颈,而现代人工智能工具能实现文本快速生成、重复率控制及结构优化。基于对九款主流平台的对比分析表明,科学运用…

张小明 2025/12/31 17:03:25 网站建设