仿照std::map定制一个Dictionary

在C#中类似C++标准库中关联容器map介绍 C#中使用Dictionary,C++使用std::map。map的内部实现是红黑树,Dictionary的实现是哈希表。DotNet中也有用树实现的字典类结构,叫SortedDictionary,似乎用得不多,效率也没有哈希表高,不过可以保持插入的数据是有序的。下面的对比是通过字符串来检索整数,为了写起来方便,C++中字符串直接用了LPCTSTR,并且typedef std::map map_t 阅读详情

以前在做一个编译器的时候,碰到这样一个问题:编译器把所有的标识符(identifier)字符串存储在一个String Table中,其实就是一个std::vector<std::string>,便于用数字来引用,但是在查找时却要根据字符串来匹配,速度显然不行。于是我不得不自己编一个Dictionary,存储的是<__int64,Entry>值对,Entry是这个标识符的入口,而__int64则是该标识符在String Table中的索引,查找时也是根据string来比较的。这样既能保证查找的效率,又能保留标识符的索引。
现在趁还记得,写下来再说。
为简化情形,先假设已经定义的如下的类:

class Entry;

其内容不重要,意义就是标识符的入口。
自定义的类里面,最重要的就是一个Comparator类,这个类的作用是告诉我们的Dictionary,该如何比较传给它的参数:__int64和std::string。我把String Table作为模板参数__StrTbl,而__StrTbl::U8就是__int64。仿照标准库的代码,具体实现如下:

#include <map>

template<class __StrTbl>class Comparator
    :public std::binary_function<std::string,typename __StrTbl::U8,bool>
{
public:
    typedef typename __StrTbl::U8 U8;
    typedef std::binary_function<std::string,U8,bool> __MyBase;
    typedef typename __MyBase::first_argument_type first_argument_type;
public:
    ~Comparator(){}
    explicit Comparator(const __StrTbl & st):StrTbl_(st){}
    template<typename T1,typename T2>
        bool operator ()(const  T1 & left,const  T2 & right) const{
            return DataTrans(left) < DataTrans(right);
        }
    const __StrTbl & StrTable() const{
        return StrTbl_;
    }
private:
    const std::string & DataTrans(const std::string & val) const{return val;}
    const std::string & DataTrans(U8 index) const{return StrTbl_[index];}
private:
    const __StrTbl & StrTbl_;
};

注意到Comparator的构造函数必须要传const __StrTbl &,原因是很显然的。
然后就是operator ()()的传入参数类型,我都用模板参数,但是用DataTrans()来转化成__StrTbl里对应的字符串。其余的几个typedef和const函数就没什么的好说的了。

现在可以定义Dictionary类了,和Comparator类一样,它也需要一个模板参数__StrTbl,而。仿照标准库的map,实现如下:

#include "Comparator.h"
#include "Entry.h"

template<class __StrTbl>class Dictionary:
    public std::_Tree<
        std::_Tmap_traits<
            typename __StrTbl::U8,
            Entry,
            Comparator<__StrTbl>,
            std::allocator<std::pair<
                const typename __StrTbl::U8,
                Entry> >
            ,false
        >
    >
{
public:
    typedef typename __StrTbl::U1 U1;
    typedef typename __StrTbl::U4 U4;
    typedef typename __StrTbl::U8 U8;
    typedef Dictionary _Myt;
    typedef U8 key_type;
    typedef Entry mapped_type;
    typedef Entry referent_type;    // retained
    typedef Comparator<__StrTbl> key_compare;
    typedef std::_Tree<std::_Tmap_traits<key_type,mapped_type,key_compare,std::allocator<std::pair<const key_type,mapped_type> >,false> > _Mybase;
    typedef typename _Mybase::value_compare value_compare;
    typedef typename _Mybase::allocator_type allocator_type;
    typedef typename _Mybase::size_type size_type;
    typedef typename _Mybase::difference_type difference_type;
    typedef typename _Mybase::pointer pointer;
    typedef typename _Mybase::const_pointer const_pointer;
    typedef typename _Mybase::reference reference;
    typedef typename _Mybase::const_reference const_reference;
    typedef typename _Mybase::iterator iterator;
    typedef typename _Mybase::const_iterator const_iterator;
    typedef typename _Mybase::reverse_iterator reverse_iterator;
    typedef typename _Mybase::const_reverse_iterator const_reverse_iterator;
    typedef typename _Mybase::value_type value_type;
    //my declarations
    typedef typename key_compare::first_argument_type first_argument_type;
private:
    iterator Lower_bound(const first_argument_type & val)
    {    // find leftmost node not less than _Keyval in mutable tree
        return (_TREE_ITERATOR(_LBound(val)));
    }
    _Nodeptr _LBound(const first_argument_type & val) const
    {    // find leftmost node not less than _Keyval
        _Nodeptr _Pnode = _Root();
        _Nodeptr _Wherenode = _Myhead;    // end() if search fails
        while (!_Isnil(_Pnode))
            if (this->comp(_Key(_Pnode), val))
                _Pnode = _Right(_Pnode);    // descend right subtree
            else{    // _Pnode not less than _Keyval, remember it
                _Wherenode = _Pnode;
                _Pnode = _Left(_Pnode);    // descend left subtree
            }
            return (_Wherenode);    // return best remembered candidate
    }
public:
    ~Dictionary(){}
    explicit Dictionary(const __StrTbl & strtbl):_Mybase(key_compare(strtbl), allocator_type()),strTbl_(strtbl){}
    iterator Query(const first_argument_type & val){    // find an element in mutable sequence that matches val
        iterator _Where = Lower_bound(val);
        return (_Where == end() || this->comp(val, _Key(_Where._Mynode())) ? end() : _Where);
    }
    bool Has(const first_argument_type & val){
        return Query(val) != end();
    }
    template<class __Symbol>
        void AddEntry(const __Symbol & sym,U4 index,U4 subIndex){
            insert(value_type(sym.Text(),mapped_type(U1(__Symbol::SymType),index,subIndex)));
        }
private:
    const __StrTbl & strTbl_;
};

在AddEntry()里出现了几个新的类名,__Symbol是符号表类,U4和U1分别为unsigned long和unsigned __int8。
insert需要一个std::pair(U8,Entry),前者是sym.Text()的返回值,后者是mapped_type(U1(__Symbol::SymType),index,subIndex),其实就是Entry的构造函数,具体传的参数就与实际情况有关了。
时间紧,现在吃饭去了!

C++ 如何表示dict 在C++中,可以使用std::map或std::unordered_map来表示字典。‌ std::map std::map是一种有序的关联容器,键值对按键排序。它使用红黑树实现,保证了键的唯一性和有序性。创建和使用std::map的示例代码如下: 阅读详情

相关推荐

C#Map映射各个方式性能大比拼

C#Map映射各个方式性能大比拼,主要测试了各种方式情况下,由一个对象生成另一个相同对象副本,1是列举了常用方式;2是各个方式的性能分析;如果你是喜欢深究其原理的C#开发者,此示例绝对值得你拥有。

C#__Dictionary类 __类似java Map 键值对

需求:现在要用到数据库的某两个**对应**字段,但是不能反复应用数据库,因为这样频繁调用数据库影响速度。So,事情还是要解决的。由于之前接触过java中的各种Map,于是就考虑在C# 中的有没有类似的东西。 解决:遇到问题第一时间问度娘,查了一下才知道,有个类叫Dictionary 作用和Map差不多,能够存储键值对,也许有其它的解决方法,但是现在我决得这个还是比较靠谱的。 Dictionary<K

llccing的专栏 5939

VLM,VLA,VLN的区别与联系

VLM 提供了理解世界的“眼睛和大脑”,VLN 赋予了这个智能体在空间中“移动的双腿”,而 VLA 则进一步赋予了它“灵巧的双手”来改变世界。三者共同构成了一个完整具身智能体的核心能力模块。

l0409044222的博客 1311

c# 中类似与java的Map 与 HashMap

[code="java"] import java.util.*; Map map = new HashMap(); map.add(o); [/code] [code="c#"] using system; using system.Collections.Generic; IDictionary map = new Dictionary(); map.Ad...

chanball的专栏 5363

智能车八邻域图像算法_二

智能车八邻域图像算法 文章目录智能车八邻域图像算法前言一、一些想法二、生长方向的使用1.点的生长方向的表示2. 用点的生长方向来做初步判断1.引入库2.读入数据总结 前言 上一篇里面讲过用八邻域来获得赛道边界:智能车八邻域图像算法 当已经能稳定获得赛道边界时,就可以进行元素识别,获得偏差了。 这里就介绍一下我的一些思路。 早在前两年,优快云上就有一篇关于八邻域如何处理元素的文章第十五届全国大学生智能汽车竞赛-双车组三轮图像处理总结,写得很好,我当时也参考了这篇文章,但是我觉得不是很详细,所以我这里想写得

技术缝合怪的博客 1万+

TensorRT(C++)部署 Pytorch模型

众所周知,python训练pytorch模型得到.pt模型。但在实际项目应用中,特别是嵌入式端部署时,受限于语言、硬件算力等因素,往往需要优化部署,而tensorRT是最常用的一种方式。本文以yolov5的部署为例,说明模型部署在x86架构上的电脑端的流程。(部署在Arm架构的嵌入式端的流程类似)。

女神sha手的博客 5404

C#中的Map(Dictionary)

C#中的Map集合Dictionary

欢迎来到我的博客 6429

从零构建虚幻引擎体积云:参数调优与性能平衡的艺术

本文深入探讨了在虚幻引擎中构建逼真体积云系统的关键技术,包括Sky Atmosphere、Volumetric Cloud和Exponential Height Fog三大核心组件的协同工作。重点解析了体积云材质的高级控制、光照阴影的物理模拟以及性能优化策略,帮助开发者在视觉效果与性能之间找到最佳平衡点。

weixin_29012677的博客 938

C#中Dictionary的用法及用途实例

如题

lvguangj的专栏 1152

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++小学组:带解析)(7月4日试卷一)【文末附答案和解析】

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++小学组:带解析)(7月4日试卷一)【文末附答案和解析】

王老师青少年编程 1738

YOLOv8改进 | 注意力机制 | 添加DAttention (DAT)注意力机制实现极限涨点

本文给大家带来的是YOLOv8改进DAT的教程,其发布于2022年CVPR2022上同时被评选为Best Paper,由此可以证明其是一种十分有效的改进机制,其主要的核心思想是:引入可变形注意力机制和动态采样点(听着是不是和可变形动态卷积DCN挺相似)。同时在网络结构中引入一个DAT计算量由8.9GFLOPs涨到了9.4GFLOPs。本文的讲解主要包含三方面:DAT的网络结构思想、DAttention的代码复现,如何添加DAttention到你的结构中实现涨点,下面先来分享我测试的对比图。

Snu77的博客 1万+

C++ std::string 和std::map实现原理

和std::map在 C++ 中的实现原理基于不同的数据结构,但都提供了高效的操作和灵活性。

xy18990的博客 835

华为OD机试真题 新系统 2026-08-02 C++ 实现【战士技能规划设计】

你为一款动作游戏设计战士角色的技能。战士每个技能会消耗不同能量,释放技能有两个约束:连续释放技能数量不能超过 m 个,技能能量总和不能超过能量上限 k;如果超过则必须中断当前技能,进入调息状态,也就是分段。

MISAYAONE的博客 75

C#中Dictionary<TKey,TValue>和C++std::map<TK,TV>的对比

C#中使用Dictionary,C++使用std::map。map的内部实现是红黑树,Dictionary的实现是哈希表。DotNet中也有用树实现的字典类结构,叫SortedDictionary,似乎用得不多,效率也没有哈希表高,不过可以保持插入的数据是有序的。下面的对比是通过字符串来检索整数,为了写起来方便,C++中字符串直接用了LPCTSTR,并且typedefstd::map map_

kinky07的专栏 7194

深入解析:AndroidManifest.xml 与 Qt 6.7.0 的整合

本文探讨了在Qt 6.7.0和CMake构建Android应用时,AndroidManifest.xml未被正确识别的问题。通过分析CMake配置错误、文件路径问题等可能原因,提出了在CMakeLists.txt中明确指定路径、确保目录结构正确等解决方案,并给出了示例项目演示。文章强调正确配置AndroidManifest.xml对获取权限和应用功能的重要性,为Qt开发者提供了实用的调试建议。

2501_90323865的博客 110

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

[C++/object c]_[初级]_[std::map容器的使用总结和NSDictionary词典使用总结]

map容器 场景:map的元素是一对对的“关键字―值”组合,“关键字”用于搜寻,而“值”用来表示我们要存取的数据。 在map容器中,每个关键字只能出现一次,不能重复 void TestMap() { typedef map gAAMap; gAAMap m; cout << "map ========="<< endl; m.insert(pair(1,"aaaaa")); m.i

moqj_123的专栏 3948

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C++ std::map用法简介

#include "map" //引入头文件初始化:std::map &lt;int, std::string&gt; _map1; //初始化 //c++11中引入的,可以直接在初始化时赋值 std::map &lt;int, std::string&gt; _map = { {0,"11"}, {2,"22"}, {3,"33"}, };插入:// 如果已经存在

Stay Hungry 5万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

std::map的使用

std::map的使用   一. std::map的定义 // std::map 的定义 template class _Ty, // Value class _Pr = less, // 比较器 class _Alloc = allocator > > // 内存分配器 class map : public _Tree > // 父类(红黑树) { ...... }

cay22的专栏 2586

c#中的“map”——Dictionary容器类

今天学习别人写的demo的时候第一次看到了 Dictionary&lt;string, string&gt; dic = new Dictionary&lt;string, string&gt;(); 然后搜索了一下暂时发现这个东西应该就是在java中的map了吧。...

qq_40290948的博客 2万+

优化做缓存用的std::map<std::string, X> (自己的C++小工具系列1)

https://zhuanlan.zhihu.com/p/24980767 优化做缓存用的std::map<std::string, X> (自己的C++小工具系列1)

szq2k08的专栏 5213
上一篇: 上次素数程序增强版
下一篇: 求类成员在类中的偏移量
daidodo
博客等级 码龄22年 43粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值