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

MFC中CMap类的用法和原理

1、CMap 的原理

CMap 是一个基于哈希表的映射类,它将唯一键映射到对应的值。其内部实现依赖于哈希算法,通过哈希函数将键转换为哈希值,然后将哈希值映射到哈希表中的某个位置。如果多个键的哈希值相同(即哈希冲突),CMap 会使用链表来解决冲突。

1.1关键点

1.1.1 哈希函数:
CMap 使用模板函数 HashKey() 来计算键的哈希值。默认情况下,HashKey() 假设键是一个指针,并将其转换为 DWORD。对于字符串类型(如 LPCSTR 和 LPCWSTR),CMap 提供了专门的哈希函数实现。
如果使用自定义类型作为键,需要提供自己的哈希函数。
1.1.2 哈希表大小:
哈希表的大小会影响性能。如果哈希表太小,可能会导致大量冲突;如果太大,则会浪费内存。可以通过调用 InitHashTable 方法来初始化哈希表并指定其大小。
1.1.3 存储结构:
CMap 内部使用一个哈希表来存储键值对。每个哈希表条目可能是一个链表,用于存储具有相同哈希值的键值对。

2.CMap 的用法

2.1. 定义和初始化

CMap 是一个模板类,需要指定键类型、键的参数类型、值类型和值的参数类型。例如:
下面展示一些 内联代码片

CMap<int, int, CString, CString> myMap; // 键为 int,值为 CString

在使用 CMap 之前,建议调用 InitHashTable 方法初始化哈希表:

myMap.InitHashTable(101); // 哈希表大小为 101

2.2 插入键值对

使用 SetAt 方法插入键值对:

myMap.SetAt(1, _T("Value1"));
myMap.SetAt(2, _T("Value2"));

也可以使用 operator[] 插入或修改键值对:

myMap[3] = _T("Value3");

3. 查找键值对

使用 Lookup 方法查找键对应的值:

CString value;
if (myMap.Lookup(1, value))
{
    // 找到键为 1 的值
    TRACE(_T("Value: %s\n"), value);
}

4. 遍历映射

可以使用 GetStartPosition 和 GetNextAssoc 方法遍历映射中的所有键值对:

POSITION pos = myMap.GetStartPosition();
int key;
CString value;
while (pos != NULL)
{
    myMap.GetNextAssoc(pos, key, value);
    TRACE(_T("Key: %d, Value: %s\n"), key, value);
}

5. 删除键值对

使用 RemoveKey 方法删除指定键的键值对:

myMap.RemoveKey(1); // 删除键为 1 的键值对

也可以使用 RemoveAll 方法清空整个映射:

myMap.RemoveAll();

6. 获取映射的大小

使用 GetSize 或 GetCount 方法获取映射中的元素数量:

int size = myMap.GetSize();
TRACE(_T("Map size: %d\n"), size);

3.注意事项

3.1 键的唯一性:
CMap 要求键是唯一的。如果尝试插入一个已经存在的键,SetAt 方法会覆盖原有的值。
3.2 自定义键类型:
如果使用自定义类型作为键,需要提供哈希函数和比较函数。默认情况下,CMap 使用 HashKey 函数计算哈希值,并使用 operator== 比较键。
3.3 性能优化:
选择合适的哈希表大小可以提高性能。哈希表大小通常是质数,可以减少冲突。
3.4 序列化:
如果需要将 CMap 对象序列化到文件,可以使用 Serialize 方法。CMap 会自动序列化其所有元素。
示例代码:

#include <afx.h>
#include <afxtempl.h>
#include <iostream>

int main()
{
    CMap<int, int, CString, CString> myMap;
    myMap.InitHashTable(101);

    // 插入键值对
    myMap.SetAt(1, _T("Value1"));
    myMap.SetAt(2, _T("Value2"));
    myMap[3] = _T("Value3");

    // 查找键值对
    CString value;
    if (myMap.Lookup(2, value))
    {
        std::wcout << L"Key 2: " << value.GetString() << std::endl;
    }

    // 遍历映射
    POSITION pos = myMap.GetStartPosition();
    int key;
    while (pos != NULL)
    {
        myMap.GetNextAssoc(pos, key, value);
        std::wcout << L"Key: " << key << L", Value: " << value.GetString() << std::endl;
    }

    // 删除键值对
    myMap.RemoveKey(1);
    myMap.RemoveAll();

    return 0;
}

以上就是MFC中CMap类的简单用法。

相关文章:

  • 做动态h5的网站品牌广告视频
  • 学习网站建设的书沧州百度推广公司
  • 做天猫转让网站怎么做网站教程视频
  • 浙江省城乡住房建设部网站今天重大新闻头条新闻
  • 企业网站 价格0元免费做代理
  • 自己做网站视频教程黑帽seo是什么意思
  • 【机器人】复现 GraspNet 端到端抓取点估计 | PyTorch2.3 | CUDA12.1
  • c++的特性——多态
  • 服务热升级的方法
  • C++ 中的 decltype:从表达式中推断类型(二十八)
  • RK3588使用笔记:纯linux系统下基础功能配置(不定期更新)
  • MySQL内存管理机制详解
  • 【差分隐私相关概念】数据立方体(Data Cube)
  • C#里使用libxl的对齐/边框/颜色
  • 【极速版 -- 大模型入门到进阶】Transformer: Attention Is All You Need -- 第一弹
  • 基于python大数据的旅游可视化及推荐系统
  • JavaScript中var、let和const的区别
  • 深入理解分布式事务Saga,从入门到面试热点分析详解
  • 05-021-自考数据结构(20331)- 动态查找-例题分析
  • [首发]烽火HG680-KD-海思MV320芯片-2+8G-安卓9.0-强刷卡刷固件包
  • 计算机Python程序代码Java编写web系统c++代做qt设计接单php开发
  • 可发1区的超级创新思路(python\matlab实现):MPTS+Lconv+注意力集成机制的Transformer时间序列模型
  • 【Ollama】大模型运行框架
  • C++进阶——位图+布隆过滤器+海量数据处理
  • Docker使用ubuntu
  • SQLMesh调度系统深度解析:内置调度与Airflow集成实践