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

wpf入可以做网站吗简单的网页设计

wpf入可以做网站吗,简单的网页设计,中堂镇做网站,网站聚合怎么做文章目录 封装哈希表实现 unordered_map、unordered_set1. 如何复用前面写过的哈希表?1.1 unordered_map 的结构1.2 unordered_set 的结构2. 容器支持 insert3. 迭代器的支持3.1 实现哈希表的迭代器3.2 unordered_map 的迭代器实现3.3 unordered_set 的迭代器实现 4…

文章目录

  • 封装哈希表实现 `unordered_map`、`unordered_set`
    • 1. 如何复用前面写过的哈希表?
    • 1.1 `unordered_map` 的结构
    • 1.2 `unordered_set` 的结构
    • 2. 容器支持 insert
    • 3. 迭代器的支持
      • 3.1 实现哈希表的迭代器
      • 3.2 `unordered_map` 的迭代器实现
      • 3.3 `unordered_set` 的迭代器实现
    • 4. `unordered_map` 支持 []

封装哈希表实现 unordered_mapunordered_set

在前面我们已经讲过 unordered_mapunordered_set 这两种容器,又讲了哈希表的实现。这次就通过封装哈希表实现 unordered_mapunordered_set

我们知道哈希表有两种处理冲突的策略,分别是:开放寻址法、链地址法(也称哈希桶,我自己习惯叫这个,下面也用这个叫法了)。个人认为哈希桶的实现更为简单,所以下面的讲解是封装哈希桶来实现的。

因为封装 unordered_map、unordered_set 的操作和前面的封装 map、set 比较相似你,感兴趣的也可以去看看我前面写的: 封装红黑树实现 mymap、myset

1. 如何复用前面写过的哈希表?

前面我实现哈希表的时候,采用的是 K,V 结构的模板参数,但是这样实现的话就等于写死了。我们只能通过封装 K,V 结构的哈希表去实现 unordered_map,而想要实现 unordered_set的话,我们还需要写一个代码高度相似的 K 结构的哈希表。这在步骤上明显比较繁琐,而且后续维护也不方便。那有没有方法能够解决这种高度相似的代码问题呢?使用模板!

我们都知道,不管是 unordered_map 还是 unordered_set 它们都共同拥有着一个键 K,只不过 unordered_map 的值是额外的 V,而 unordered_set 的值就是它的键 K。所以我们可以这么设计,第一个模板参数仍为 K,用于保存哈希表的键,但是第二个参数 T 用于保存哈希表实际存储的数据(unordered_map 就传一个 pair<K, V> 给模板参数 T,而 unordered_set 就传一个 K 给模板参数 T,这样就能让编译器自动为我们生成两套底层存储数据不同的哈希表)。因为底层存储数据类型不同,所以我们还需要一个模板参数 KeyOfT 去统一我们对数据的读取和使用。

	// 修改前template<class K, class V>struct HashNode{pair<K, V> _kv;HashNode<K, V>* _next;HashNode(const pair<K, V>& kv):_kv(kv), _next(nullptr){}};template<class K, class V, class Hash = HashFunc<K>>class HashTable{typedef HashNode<K, V> Node;public:HashTable():_tables(__stl_next_prime(0)), _n(0){}private:vector<Node*> _tables; // 指针数组size_t _n = 0;		   // 表中存储数据个数}// 修改后template<class T>struct HashNode{T _data;HashNode<T>* _next;HashNode(const T& data):_data(data), _next(nullptr){}};template<class K, class T, class KeyOfT, class Hash>class HashTable{typedef HashNode<T> Node;public:HashTable():_tables(__stl_next_prime(0)), _n(0){}private:vector<Node*> _tables; // 指针数组size_t _n = 0;		  // 表中存储数据个数};

KeyOfT 的作用
前面我们说过,KeyOfT 是用来统一我们对数据的读取和使用的,其实这玩意就是相当于传一个仿函数,unordered_map 的话就返回 kv.first,而 unordered_set 的话就直接返回 key

1.1 unordered_map 的结构

底层存储的就是一个哈希表,但是我们前面说了,它的第一个模板参数为 K,第二个模板参数用于存储他真正的数据,所以为 pair<const K, V>

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;}};private:hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT, Hash> _ht;
};

1.2 unordered_set 的结构

unordered_map 最本质的区别就是它底层存储的哈希表中存储的数据是 K 而非 pair<K, V>

	template<class K, class Hash = HashFunc<K>>class unordered_set{struct SetKeyOfT{const K& operator()(const K& key){return key;}};private:hash_bucket::HashTable<K, const K, SetKeyOfT, Hash> _ht;};

2. 容器支持 insert

直接在容器中通过调用底层接口的 Insert 即可。

		// unordered_mapbool insert(const pair<K, V>& kv){return _ht.Insert(kv);}// unordered_setbool insert(const K& key){return _ht.Insert(key);}

3. 迭代器的支持

我们这里所说的 unordered_mapunordered_set 其实就是一层壳,我们是通过外边这层壳对底层数据结构的操作进行统一。实现这层壳主要还是调用底层接口,所以我们得先实现底层数据结构哈希表的迭代器

3.1 实现哈希表的迭代器

我们这个哈希表是通过哈希桶的方式来实现的,所以迭代器得存储两个数据。一个是哈希表的表(你是在这个表里面通过哈希值找桶),一个是当前节点的指针(在找到桶之后,你得记录你是在桶中链表的哪一个节点)。

我们迭代器的实现方法仍然和之前实现迭代器的方法一样,使用 <T, Ref, Ptr> 形式,这样可以在要使用的地方通过传普通类型const类型 来让编译器为我们生成 普通迭代器和 const 迭代器。

注意:
因为我们一般迭代器的实现是放在数据结构前面的,而这里的迭代器又要存储哈希表,所以要迭代器前面先声明哈希表

	// 前置声明template<class K, class T, class KeyOfT, class Hash>class HashTable;template<class K, class T, class Ref, class Ptr, class KeyOfT, class Hash>struct HTIterator{typedef HashNode<T> Node;typedef HashTable<K, T, KeyOfT, Hash> HT;typedef HTIterator<K, T, Ref, Ptr, KeyOfT, Hash> Self;Node* _node;const HT* _ht;HTIterator(Node* node, const HT* ht):_node(node), _ht(ht){}};

又因为我们这里的迭代器是要访问哈希表中的数据的,而哈希表中的数据又是私有的,所以在哈希表类中还得做一下友元声明

		// 在哈希表类中做下友元声明template<class K, class T, class Ref, class Ptr, class KeyOfT, class Hash>friend struct HTIterator;

operator*operator->operator!=的实现大家应该都挺熟的了,这里只讲解一下 operator++ 的实现,以便于支持范围for循环,operator-- 的思路和 ++ 刚好相反,这里就不实现了,感兴趣的自己去实现一下。

因为是哈希桶的实现,所以数据处于哈希表的桶中。如果节点所在的桶后面还有数据的话,直接通过链表指针走到该桶的下一个节点即可;如果桶后面没有数据的话,也就是说这个桶走完了,那么我们就要走到哈希表中下一个不为空的桶中开始找,下一个节点就是那个桶上挂的第一个节点

那么如何表示走到 end 位置呢?因为我们是用节点指针表示当前节点,那么很自然的想到 end 位置应该是 nullptr。所以当 hashi 的大小等于哈希桶的数量时,直接给迭代器赋值为 nullptr

		Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self& s){return _node != s._node;}Self& operator++(){if (_node->_next){// 当前桶还有数据,走到桶的下一个节点_node = _node->_next;}else{// 当前桶走完了,走到下一个不为空的桶KeyOfT kot;Hash hash;// 计算当前桶的哈希值size_t hashi = hash(kot(_node->_data)) % _ht->_tables.size();++hashi;while (hashi < _ht->_tables.size()){_node = _ht->_tables[hashi];if (_node)break;else++hashi;}// 所有桶都走完了,end()给的空标识的_nodeif (hashi == _ht->_tables.size()){_node = nullptr;}}return *this;}

3.2 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();}bool insert(const pair<K, V>& kv){return _ht.Insert(kv);}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;};

3.3 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();}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;};

4. unordered_map 支持 []

要支持 unordered_map[],主要需要修改 insert 返回值,将 HashTableinsert 的返回值修改为 pair<Iterator, bool> Insert(const T& data)

		pair<Iterator, bool> Insert(const T& data){KeyOfT kot;Iterator it = Find(kot(data));if (it != End())return { it, false };Hash hash;// 负载因子 == 1 时扩容if (_n == _tables.size()){vector<Node*> newTable(_tables.size() * 2);for (size_t i = 0; i < _tables.size(); ++i){Node* cur = _tables[i];while (cur){Node* next = cur->_next;// 头插到新标size_t hashi = hash(kot(cur->_data)) % newTable.size();cur->_next = newTable[hashi];newTable[hashi] = cur;cur = next;}_tables[i] = nullptr;}_tables.swap(newTable);}size_t hashi = hash(kot(data)) % _tables.size();// 头插Node* newnode = new Node(data);newnode->_next = _tables[hashi];_tables[hashi] = newnode;++_n;return  { Iterator(newnode, this), false };}

统一 unordered_mapunordered_setinsert 接口:

		// unordered_mappair<iterator, bool> insert(const pair<K, V>& kv){return _ht.Insert(kv);}// unordered_setpair<iterator, bool> insert(const K& key){return _ht.Insert(key);}

最后在 unordered_map 中实现 operator[]

		V& operator[](const K& key){pair<iterator, bool> ret = insert({ key, V() });return ret.first->second;}
http://www.dtcms.com/wzjs/186863.html

相关文章:

  • 泉州建设网站公司吗网页设计作品
  • 网络服务提供者知道或者应当知道网络用户利用其网络服务侵害他电脑优化大师下载安装
  • 金华网站制作系统怎么做好市场宣传和推广
  • 平台公司工作总结seo咨询推广
  • 电商网站建设行情网站页面分析作业
  • 济南建设网站网站软件开发
  • wordpress 网站迁移seo标题关键词优化
  • 用搬瓦工做网站广州seo推荐
  • 专业的移动网站建设公电商关键词seo排名
  • wordpress购物 app百度快速优化软件
  • 网页美工设计简单流程推广seo优化公司
  • 网站接入商爱站网关键词挖掘查询工具
  • 珠海网站建设的公司长春百度推广电话
  • py可以做网站吗长沙网红打卡地
  • 学做陶艺作品的网站免费的舆情网站app
  • 网站一个页面多少钱恩城seo的网站
  • 网站建设 gei l fb站推广网站2022
  • 网站的建设与维护需要资质吗搜狗站长平台验证不了
  • 沈阳公司网站建设爱站网长尾关键词挖掘查询工具
  • 网站建设是属于虚拟产品吗性价比高seo的排名优化
  • 网站建设及 维护百度竞价网站
  • 找外国男人做老公网站网址收录平台
  • wordpress主题ent破解版廊坊网络推广优化公司
  • 那个网站有免费的模板河南郑州最近的热搜事件
  • 南昌网站建设培训学校惠州网站seo排名优化
  • 南通企业建站程序seo搜索引擎优化原理
  • java php做网站的区别今日刚刚发生的军事新闻
  • 网站模版免费下载seo经典案例分析
  • 武汉哪家网站建设公司好网站建设优化的技巧
  • 找室内设计师上哪个网站知乎推广渠道